1 条题解

  • 0
    @ 2025-8-24 22:48:32

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar maomao233
    私信互关aaa 因为 400 粉儿以后看不到了。 ⎛⎝≥⏝⏝≤⎛⎝

    搬运于2025-08-24 22:48:32,当前版本为作者最后更新于2023-07-16 23:28:53,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    题目传送门

    Easy Version 传送门

    感觉这题评黄有些过分,应该是中位橙的难度,但真的很烧脑干

    分析

    本题难点在于特别特别为复杂的坐标转换。

    首先是读入,大致有两种读入方法。第一种是按题面的输入,题面写的是输入的 ax,y,za_{x,y,z} 表示的是格子 (y,z,x)(y,z,x),所以若三重循环的变量分别为 i,j,li,j,l,则应该读入 aj,l,ia_{j,l,i};第二种就是直接输入 ai,j,la_{i,j,l}。其实本质没有什么区别,本篇题解就以第一种输入为例:

    int n,m,k;
    	cin>>n>>m>>k;
    	for(int i=1;i<=k;i++)
    	{
    		for(int j=1;j<=n;j++)
    		{
    			for(int l=1;l<=m;l++)
    			{
    				cin>>a[j][l][i];
    			}
    		}
    	}
    

    然后我们再沿三种视图来讲解:

    正视图

    正视图要求自上而下自左至右。因此我们首先需要倒序枚举 zz 轴(即变量 kk,代表长方体的高),其次正序枚举 xx 轴(即变量 nn,代表长方体的长),最后再是正序往后mm 个(即长方体的宽)小正方体即可。在枚举中,输出每一格的情况即可。

    正视图部分代码:

    for(int i=k;i;i--)
    	{
    		for(int j=1;j<=n;j++)
    		{
    			int flag=0;
    			for(int l=1;l<=m;l++)
    			{
    				if(a[j][l][i])
    				{
    					flag=1;
    					break;
    				}
    			}
    			cout<<flag<<" ";
    		}
    		putchar('\n');
    	}
    

    左视图

    左视图要求自上而下自后至前。因此我们首先需要倒序枚举 zz 轴(即变量 kk,代表长方体的高),其次倒序枚举 yy 轴(即变量 mm,代表长方体的宽),最后再是正序往右nn 个(即长方体的长)小正方体即可。在枚举中,输出每一格的情况即可。

    但是这里还需注意,这里不应该再是 aj,l,ia_{j,l,i} 了,因为循环变量本身就“代表”了其第一次所对应的标准变量,比如 ii 对应 kk,那么这次它也就“代表” kk。所以按此规律,原本变量为 n,m,kn,m,k,现在对应一下,这里应该为 al,j,ia_{l,j,i}。(因为在这里 ii 代表 kkjj 代表 mmll 代表 nn,标准顺序是 n,m,kn,m,k,所以循环变量应该排序成 l,j,il,j,i。)

    这个规律通用于三个俯视图。当然,你也可以称其为小技巧。

    左视图部分代码:

    for(int i=k;i;i--)
    	{
    		for(int j=m;j;j--)
    		{
    			int flag=0;
    			for(int l=1;l<=n;l++)
    			{
    				if(a[l][j][i])
    				{
    					flag=1;
    					break;
    				}
    			}
    			cout<<flag<<" ";
    		}
    		putchar('\n');
    	}
    

    俯视图

    俯视图要求自后至前自左至右。因此我们首先需要倒序枚举 yy 轴(即变量 mm,代表长方体的宽),其次正序枚举 xx 轴(即变量 nn,代表长方体的长),最后再是正序往下kk 个(即长方体的高)小正方体即可。在枚举中,输出每一格的情况即可。

    这里循环变量也需对应,按“左视图”里的方法对应后,此处应为 aj,i,la_{j,i,l}

    俯视图部分代码:

    for(int i=m;i;i--)
    	{
    		for(int j=1;j<=n;j++)
    		{
    			int flag=0;
    			for(int l=1;l<=k;l++)
    			{
    				if(a[j][i][l])
    				{
    					flag=1;
    					break;
    				}
    			}
    			cout<<flag<<" ";
    		}
    		putchar('\n');
    	}
    

    完整代码就不给了,组合一下四段代码就是。

    最后再说一个小技巧吧。下次遇到这种题目,各位如果实在不知道或想不出来要不要倒序或怎么将循环变量对应,就可以尝试枚举所有种情况。枚举这 i,j,li,j,l,一共也就 2×3=62\times3=6 种可能。再加上倒序,一共也就 1212 种可能,依次尝试即可。虽然说这有点类似于骗分,但至少可以 AC,赛时我就是这样 AC 的。

    • 1

    [入门赛 #14] Three-View Projection (Hard Version)

    信息

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