题目描述
小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣的内容。最近,他准备给小朋友们讲解立体图,请你帮他画出立体图。
小渊有一块面积为 m×n 的矩形区域,上面有 m×n 个边长为 1 的格子,每个格子上堆了一些同样大小的积木(积木的长宽高都是 1),小渊想请你打印出这些格子的立体图。
我们定义每个积木为如下格式,并且不会做任何翻转旋转,只会严格以这一种形式摆放:
char box[6][8]={
"..+---+",
"./ /|",
"+---+ |",
"| | +",
"| |/.",
"+---+.."
};
每个顶点用 1 个加号 + 表示,长用 3 个 − 表示,宽用 1 个 / 表示,高用两个 | 表示。
字符 +,−,/,| 的 ASCII 码分别为 43,45,47,124。
字符 . (ASCII 码 46)需要作为背景输出,即立体图里的空白部分需要用 . 来代替。
立体图中,定义位于第 (m,1) 的格子(即第 m 行第 1 列的格子)上面自底向上的第一块积木(即最下面的一块积木)的左下角顶点为整张图最左下角的点。
输入格式
输入文件第一行有用空格隔开的两个整数 m 和 n,表示有 m×n 个格子。
接下来的 m 行,是一个 m×n 的矩阵,每行有 n 个用空格隔开的整数,其中第 i 行第 j 列上的整数表示第 i 行第 j 列的格子上摞有多少个积木(1≤每个格子上的积木数≤100)。
输出格式
输出文件中包含题目要求的立体图,是一个 K 行 L 列的字符矩阵,其中 K 和 L 表示最少需要 K 行 L 列才能按规定输出立体图。
数据范围
1≤m,n≤50
输入样例
3 4
2 2 1 2
2 2 1 1
3 2 1 2
输出样例
......+---+---+...+---+
..+---+ / /|../ /|
./ /|-+---+ |.+---+ |
+---+ |/ /| +-| | +
| | +---+ |/+---+ |/|
| |/ /| +/ /|-+ |
+---+---+ |/+---+ |/| +
| | | +-| | + |/.
| | |/ | |/| +..
+---+---+---+---+ |/...
| | | | | +....
| | | | |/.....
+---+---+---+---+......
然后为了正确处理遮挡关系,按照从后到前、从左到右、从下到上的顺序画每个小正方体即可。
两个坐标系如下所示,我们将最靠左、前、下的小立方体,和二维坐标系中左下角的点(499,0)对齐。
然后观察可以发现二者的映射关系:设小立方体在 (x,y,z)(x,y,z) ,即第 xx 行第 yy 列第 zz 层, 则对于投影后的坐标而言:
横坐标:z 每变1,横坐标变3,x 每变1,横坐标变2;
纵坐标:x 每变1,总坐标变2,y 每变1,纵坐标变4
因此投影之后的左下角坐标是:
横坐标是 499−3z−2(n−1−x)
纵坐标是 2(n−1−x)+4y
接下来还需要确定投影之后的二维平面的范围。
最后将二维投影平面的范围内的部分输出即可。
时间复杂度
每个小立方体均需要画一次,每次需要画 6 * 7 = 42个字符,因此总时间复杂度是 O(42nmh),其中 n,m,h 分别表示长宽高。
C++代码
#include<bits/stdc++.h>
using namespace std;
const int N=500;
int n,m;
int a[N][N];
char box[6][8]={
"..+---+",
"./ /|",
"+---+ |",
"| | +",
"| |/.",
"+---+.."
};
char g[N][N];
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&a[i][j]);
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
g[i][j]='.';
int up=N,right=0;
for(int x=0;x<n;x++)
for(int y=0;y<m;y++)
for(int z=0;z<a[x][y];z++)
{
int X=499-3*z-2*(n-1-x);
int Y=2*(n-1-x)+4*y;
up=min(up,X-5);
right=max(right,Y+6);
for(int a=0;a<6;a++)
for(int b=0;b<7;b++)
if(box[a][b]!='.')
g[X-5+a][Y+b]=box[a][b];
}
for(int i=up;i<N;i++)
{
for(int j=0;j<=right;j++)
putchar(g[i][j]);
puts("");
}
return 0;
}