1 条题解
-
0
自动搬运
来自洛谷,原作者为

2023z
乘风破浪向朝阳,披荆斩棘露锋芒搬运于
2025-08-24 22:56:15,当前版本为作者最后更新于2025-07-09 16:52:58,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
今天考试正好考到了,来交一交题解 qwq
题意简述
给我们 个拼图,每块拼图的颜色、大小和两个数字 表示下一块拼图的方向和 表示下一块拼图的起点行 / 列,以及拼图的顺序。
和 的具体操作如下:
- 如果 ,将下一块拼图放在这块拼图的上边,将下一块拼图的最左边对齐这块拼图的第 列。
- 如果 ,将下一块拼图放在这块拼图的右边(当然没有拼图了就不要放了),将下一块拼图的最下边对齐这块拼图的第 行。
思路
第一眼看这题像是模拟,实际上也就是模拟,我们用一个结构体记录每一块拼图的输入信息,编号就不记录了 (因为输入时的 就是 ),然后边输入边模拟。我们知道方向只有右和上,并且 决定 ,所以矩阵一定是一直向上延伸的。初始将起点赋值为 对于每次循环,终点 计算后,从起点枚举到终点,赋值为 (颜色)。整个矩阵的高和宽也很好算,判断当前 是否大于当前边长的 坐标,更新 , 是否大于当前 坐标,更新 。哦,对,还有下一次的起点,需要分情况讨论:
-
如果 ,
-
如果 ,
注意:
坐标要从 到 输出, 坐标可以从 到 输出,最后判断如果这个点位为空输出
.否则输出对应的字母。AC code :
#include <bits/stdc++.h> using namespace std; struct node { int r, s, u, d; char b; } a[30]; // 输入的各种数据 int n, k[30], ansx = 1, ansy = 1; // ansx 表示最终输出的高,ansy 表示最终输出的宽 char s[1010][1010]; // s 表示答案数组 int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); // 超级输入输出流 qwq cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i].b >> a[i].r >> a[i].s >> a[i].u >> a[i].d; } // 输入 int x = 1, y = 1, x1 = 0, y1 = 0; // (x, y) 表示的是起点坐标,(x1, y1) 表示的是终点坐标。初始化 (x,y) == (1, 1) for (int i = 1; i <= n; i++) { cin >> k[i]; x1 = x + a[k[i]].r - 1, y1 = y + a[k[i]].s - 1; // 通过起点算出这块拼图的终点 if (x1 > ansx) // 更新 ansx ansx = x1; if (y1 > ansy) // 更新 ansy ansy = y1; for (int v = x; v <= x1; v++) { for (int j = y; j <= y1; j++) { s[v][j] = a[k[i]].b; // 把起点到终点赋值为对应的字母 } } if (a[k[i]].u == 0) // 判断方向,算出下一块拼图的起点 { x = x1 + 1, y = y + a[k[i]].d - 1; // 这里是通过找规律得出的公式 } if (a[k[i]].u == 1) { x = x1 - a[k[i]].d + 1, y = y1 + 1; // 这里也是 } } cout << ansx << ' ' << ansy << endl; // 输出 for (int i = ansx; i >= 1; i--) { for (int j = 1; j <= ansy; j++) { if (s[i][j] == '\0') // 判断这里是否被染色 s[i][j] = '.'; // 没被染色说明这里是 . cout << s[i][j]; } cout << endl; } return 0; } // 管理员求过 qwq完结撒花!!!
- 1
信息
- ID
- 9952
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 2
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者