立体图

立体图 ⁡ \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) (1m,n50)

接下来的 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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值