1 条题解

  • 0
    @ 2025-8-24 22:56:15

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 2023z
    乘风破浪向朝阳,披荆斩棘露锋芒

    搬运于2025-08-24 22:56:15,当前版本为作者最后更新于2025-07-09 16:52:58,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    今天考试正好考到了,来交一交题解 qwq

    题意简述

    给我们 n n 个拼图,每块拼图的颜色、大小和两个数字 u u 表示下一块拼图的方向和 d d 表示下一块拼图的起点行 / 列,以及拼图的顺序。

    u u d d 的具体操作如下:

    • 如果 u=0 u=0 ,将下一块拼图放在这块拼图的上边,将下一块拼图的最左边对齐这块拼图的第 d d 列。
    • 如果 u=1 u=1 ,将下一块拼图放在这块拼图的右边(当然没有拼图了就不要放了),将下一块拼图的最下边对齐这块拼图的第 d d 行。

    思路

    第一眼看这题像是模拟,实际上也就是模拟,我们用一个结构体记录每一块拼图的输入信息,编号就不记录了 (因为输入时的 i i 就是 ai a_i ),然后边输入边模拟。我们知道方向只有右和上,并且 ui u_i 决定 1disi,ri 1 \leq d_i \leq s_i,r_i ,所以矩阵一定是一直向上延伸的。初始将起点赋值为 (x,y) (x,y) (1,1) (1,1) 对于每次循环,终点 (x1,y1),x1=x+ai.r1,y1=y+ai.s1 (x1,y1) , x1=x+a_i.r-1 , y1=y+a_i.s-1 计算后,从起点枚举到终点,赋值为 ai.b a_i.b (颜色)。整个矩阵的高和宽也很好算,判断当前 x1 x1 是否大于当前边长的 ansx ansx 坐标,更新 ansx ansx y1 y1 是否大于当前 ansy ansy 坐标,更新 ansy ansy 。哦,对,还有下一次的起点,需要分情况讨论:

    • 如果 u=0 u=0 x=x1+1,y=y+aki.d1 x = x1 + 1 , y = y + a_{k_i}.d - 1

    • 如果 u=1 u=1 x=x1aki.d+1,y=y1+1 x = x1 - a_{k_i}.d + 1 , y = y1 + 1

    注意:

    x x 坐标要从 ansx ansx 1 1 输出,y y 坐标可以从 1 1 ansy ansy 输出,最后判断如果这个点位为空输出 . 否则输出对应的字母。

    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
    

    AC记录

    完结撒花!!!

    • 1

    信息

    ID
    9952
    时间
    1000ms
    内存
    512MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者