专栏文章

P1058

P1058题解参与者 7已保存评论 7

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
7 条
当前快照
1 份
快照标识符
@miqg0ful
此快照首次捕获于
2025/12/04 04:11
3 个月前
此快照最后确认于
2025/12/04 04:11
3 个月前
查看原文

思路

感觉这道题还是有思维含量的。
考虑如何得到一张立体图。
如果从前往后依次放方块是非常困难的。
所以可以从后往前建方块。
然后可以发现前面的其实可以覆盖后面方块的图,左边的可以覆盖右边的,同一个位置上面的可以覆盖下面的。所以从后往前,从左往右,从下往上作图。
具体的,可以从给出的矩阵的左上角开始建,从上往下,从左往右,在对于每一个矩阵中的位置,从下往上堆方块。堆方块时可以设置一个单位正方体的图,从图形的左下角开始,每次将纵坐标向上移动,对于单位方格有实际意义的位置,直接覆盖原来位置的字符即可。
可以用画图软件操作一下。比如这样:
理解了这些之后这题就非常简单了。
但是这样的方式在数组中存储的位置并不确定。
所以可以将作图的其实位置放在数组中间,上下左右给其充分大的空间,再在作图过程中更新打印时图的大小即可。

代码

CPP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int num[55][55],u=1e9,d=0,l=1e9,r=0;
char a[4005][4005];//答案数组
char cube[10][10]={"..+---+",
				   "./   /|",
				   "+---+ |",
				   "|   | +",
				   "|   |/.",
				   "+---+.."};//单个方块
void print(int x,int y,int h)//每个二维中同样位置从下往上堆方块
{
	x-=5;
	for(int k=1;k<=h;k++)
	{
		for(int i=0;i<6;i++)
			for(int j=0;j<7;j++)
				if(cube[i][j]!='.')
					a[x+i][y+j]=cube[i][j];
		x-=3;//打印方块起始位置移动
	}
	u=min(u,x+3);//更新上界
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>num[i][j];
	int x=3000,y=1000;
	for(int i=1;i<=n;i++)
	{
		int y_=y;
		for(int j=1;j<=m;j++)//从左到右打印
		{
			print(x,y_,num[i][j]);
			y_+=4;
		}
		r=max(r,y_+2);//右界
		x+=2;
		y-=2;
	}
	d=x-2;//下界
	l=y+2;//左界
	for(int i=u;i<=d;i++)
	{
		for(int j=l;j<=r;j++)
		{
			if(!a[i][j])cout<<".";
			else cout<<a[i][j];
		}
		cout<<'\n';
	}
	return 0;
}

评论

7 条评论,欢迎与作者交流。

正在加载评论...