立体图 \operatorname{立体图} 立体图
题目链接: luogu P1058 \operatorname{luogu\ P1058} luogu P1058
题目
小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣的内容。最近,他准备给小朋友们讲解立体图,请你帮他画出立体图。
小渊有一块面积为
m
×
n
m \times n
m×n 的矩形区域,上面有
m
×
n
m \times n
m×n 个边长为
1
1
1 的格子,每个格子上堆了一些同样大小的积木(积木的长宽高都是
1
1
1 ),小渊想请你打印出这些格子的立体图。我们定义每个积木为如下格式,并且不会做任何翻转旋转,只会严格以这一种形式摆放:
每个顶点用
1
1
1 个加号’
+
+
+ ’表示,长用
3
3
3 个”
−
-
− ”表示,宽用
1
1
1 个”
/
/
/ ”,高用两个”
∣
|
∣ ”表示。字符’
+
+
+ ’,”
−
-
− ”,”
/
/
/ ”,”
∣
|
∣ ”的 ASCII 码分别为
43
43
43 ,
45
45
45 ,
47
47
47 ,
124
124
124 。字符’
.
.
. ’ ( ASCII 码
46
46
46 )需要作为背景输出,即立体图里的空白部分需要用’
.
.
. ’来代替。立体图的画法如下面的规则:
若两块积木左右相邻,图示为:
若两块积木上下相邻,图示为:
若两块积木前后相邻,图示为:
立体图中,定义位于第
(
m
,
1
)
(m,1)
(m,1) 的格子(即第
m
m
m 行第
1
1
1 列的格子)上面自底向上的第一块积木(即最下面的一块积木)的左下角顶点为整张图最左下角的点。
输入
第一行有用空格隔开的 2 2 2 个整数 m m m 和 n n n ,表示有 m × n m \times n m×n 个格子 ( 1 ≤ m , n ≤ 50 ) (1 \le m,n \le 50) (1≤m,n≤50) 。
接下来的 m m m 行,是一个 m × n m \times n m×n 的矩阵,每行有 n n n 个用空格隔开的整数,其中第 i i i 行第 j j j 列上的整数表示第 i i i 行第 j j j 列的个子上摞有多少个积木( 1 ≤ 1 \le 1≤ 每个格子上的积木数 ≤ 100 \le 100 ≤100 )。
输出
输出包含题目要求的立体图,是一个 K K K 行 L L L 列的字符串矩阵,其中 K K K 和 L L L 表示最少需要 K K K 行 L L L 列才能按规定输出立体图。
样例输入
3 4
2 2 1 2
2 2 1 1
3 2 1 2
样例输出
......+---+---+...+---+
..+---+ / /|../ /|
./ /|-+---+ |.+---+ |
+---+ |/ /| +-| | +
| | +---+ |/+---+ |/|
| |/ /| +/ /|-+ |
+---+---+ |/+---+ |/| +
| | | +-| | + |/.
| | |/ | |/| +..
+---+---+---+---+ |/...
| | | | | +....
| | | | |/.....
+---+---+---+---+......
思路
这道题就是一道模拟题。
.
我们就分解除一个一个的小立方体,然后我们从后往前,从下往上,从左往右来一个一个构件方块。
(这样该遮掉的就自然会被遮掉,不用多加处理)
最后我们只要输出那个表就可以了。
啥?小立方体怎么弄?
就打表小正方体,每次就找到这个小正方体的左下角,从而推出全部。
而有关
K
K
K 和
L
L
L ,我们就在用小正方体填充图的过程中,找到最大的长和宽,就是
K
K
K 和
L
L
L 了。
代码
#include<cstdio>
#include<iostream>
using namespace std;
int n, m, a[1001][1001], ansx, ansy, fir[6] = {2, 1, 0, 0, 0, 0}, las[6] = {6, 6, 6, 6, 5, 4};
char dabiao[11][11] = {" +---+", " / /|", "+---+ |", "| | +", "| |/", "+---+", };
char ans[1001][1001];
void work(int x, int y) {//填充图
for (int i = 5; i >= 0; i--)
for (int j = fir[i]; j <= las[i]; j++) {
ans[x + (5 - i)][y + j] = dabiao[i][j];
ansx = max(ansx, x + (5 - i));//找到图片的尺寸
ansy = max(ansy, y + j);
}
}
int main() {
scanf("%d %d", &n, &m);//读入
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &a[i][j]);//读入
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
for (int k = 1; k <= a[i][j]; k++)
work(2 * (n - i) + 1 + 3 * (k - 1), 2 * (n - i) + 1 + 4 * (j - 1));//找到每一个小立方体的左下角
for (int i = ansx; i >= 1; i--) {
for (int j = 1; j <= ansy; j++)
if (ans[i][j] == 0) printf(".");
else printf("%c", ans[i][j]);//输出
printf("\n");
}
return 0;
}