目录
题目
小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣的内容。最近,他准备给小朋友们讲解立体图,请你帮他画出立体图。
小渊有一块面积为 m×n 的矩形区域,上面有 m×n 个边长为 1 的格子,每个格子上堆了一些同样大小的积木(积木的长宽高都是 1),小渊想请你打印出这些格子的立体图。
我们定义每个积木为如下格式,并且不会做任何翻转旋转,只会严格以这一种形式摆放:
每个顶点用 11 个加号
+
表示,长用 33 个−
表示,宽用 11 个/
表示,高用两个|
表示。字符
+
,−
,/
,|
的 ASCII 码分别为 43,45,47,124。字符
.
(ASCII 码 46)需要作为背景输出,即立体图里的空白部分需要用.
来代替。立体图的画法如下面的规则:
若两块积木左右相邻,图示为:
若两块积木上下相邻,图示为:
若两块积木前后相邻,图示为:
立体图中,定义位于第 (m,1) 的格子(即第 m 行第 1 列的格子)上面自底向上的第一块积木(即最下面的一块积木)的左下角顶点为整张图最左下角的点。
输入格式
输入文件第一行有用空格隔开的两个整数 m 和 n,表示有 m×n 个格子。
接下来的 m 行,是一个 m×n 的矩阵,每行有 n 个用空格隔开的整数,其中第 ii 行第 jj 列上的整数表示第 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
输出样例:
......+---+---+...+---+ ..+---+ / /|../ /| ./ /|-+---+ |.+---+ | +---+ |/ /| +-| | + | | +---+ |/+---+ |/| | |/ /| +/ /|-+ | +---+---+ |/+---+ |/| + | | | +-| | + |/. | | |/ | |/| +.. +---+---+---+---+ |/... | | | | | +.... | | | | |/..... +---+---+---+---+......
题解:
知识点:字符串处理、模拟、坐标变换
分析:
首先将一个小正方体的投影画出来:
char box[6][8] = {
"..+---+",
"./ /|",
"+---+ |",
"| | +",
"| |/.",
"+---+.."
};
然后为了正确处理遮挡关系,按照从后到前、从左到右、从下到上的顺序画每个小正方体即可。
两个坐标系如下所示,我们将最靠左、前、下的小立方体,和二维坐标系中左下角的点(499,0)对齐。
然后观察可以发现二者的映射关系:设小立方体在 (x,y,z)( ,即第 x 行第 y 列第 z 层, 则对于投影后的坐标而言:
- 横坐标:z 每变1,横坐标变3,x 每变1,横坐标变2;
- 纵坐标:x 每变1,总坐标变2,y 每变1,纵坐标变4
因此投影之后的左下角坐标是:
- 横坐标是 499−3z−2(n−1−x)
- 纵坐标是 2(n−1−x)+4y
接下来还需要确定投影之后的二维平面的范围。
最后将二维投影平面的范围内的部分输出即可。
这题好造孽
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define _for(i,a,b) for (int i=(a);i<(b);i++)
using namespace std;
const int N=500;
int h[N][N];
char g[N][N],box[6][8]={//预处理,注意是box[6][8],不是box[6][7],因为每个字符串末还有占位符
"..+---+",
"./ /|",
"+---+ |",
"| | +",
"| |/.",
"+---+.."
};
int main(){
int n,m,up=N,right=0;
scanf("%d%d",&n,&m);
_for(i,0,n){
_for(j,0,m){
scanf("%d",&h[i][j]);
}
}
_for(i,0,N){//预处理
_for(j,0,N){
g[i][j]='.';
}
}
_for(x,0,n){
_for(y,0,m){
_for(z,0,h[x][y]){
int X=499-3*z-((n-1-x)<<1),Y=4*y+((n-1-x)<<1);//见解析(<<1是*2的意思)
up=min(up,X-5);//整个二维立方体上边界
right=max(right,Y+6);//右边界
_for(a,0,6){//填充单位二维立方体
_for(b,0,7){
if (box[a][b]!='.'){
g[X-5+a][Y+b]=box[a][b];//自己画图理解
}
}
}
}
}
}
_for(i,up,N){//输出
_for(j,0,right+1){
putchar(g[i][j]);
}
puts("");
}
return 0;
}