小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣的内容。最近,他准备给小朋友们讲解立体图,请你帮他画出立体图。
小渊有一块面积为 m×n 的矩形区域,上面有 m×n 个边长为 1 的格子,每个格子上堆了一些同样大小的积木(积木的长宽高都是 1),小渊想请你打印出这些格子的立体图。
我们定义每个积木为如下格式,并且不会做任何翻转旋转,只会严格以这一种形式摆放:
每个顶点用 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
输出样例:
......+---+---+...+---+
..+---+ / /|../ /|
./ /|-+---+ |.+---+ |
+---+ |/ /| +-| | +
| | +---+ |/+---+ |/|
| |/ /| +/ /|-+ |
+---+---+ |/+---+ |/| +
| | | +-| | + |/.
| | |/ | |/| +..
+---+---+---+---+ |/...
| | | | | +....
| | | | |/.....
+---+---+---+---+......
思路 字符串处理,模拟
将一个小正方体的投影画出来:
char box[6][8] = {
"..+---+",
"./ /|",
"+---+ |",
"| | +",
"| |/.",
"+---+.."
};
然后为了正确处理遮挡关系,按照从后到前、从左到右、从下到上的顺序画每个小正方体即可。
#include <iostream>
#include <algorithm>using namespace std;const int N = 500;int n, m;
char box[6][8] = {"..+---+","./ /|","+---+ |","| | +","| |/.","+---+.."
};char g[N][N];
int h[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", &h[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 < h[x][y]; z++){int X = 499 - 2 * (n - 1 - x) - 3 * z;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++) printf("%c", g[i][j]);puts("");}
}