纯属自己写完题后的总结,中间借鉴了很多博客的做法。
题目:P2018 立体图
本题乍一看好像无从下手,其实理清逻辑关系后还是较为简单。
1.用一个数组单独存储单个方块。
2.创建一个输出数组(即一块画布),先创建的尽量大一点,等下再根据输入的数据计算实际需要使用的大小。
3.将方块从后到前,从左到右,从下到上存入‘画布’,这样就直接解决了重叠、遮挡的问题。
4.每一个位置的方块我们用一个点来表示其位置,我看到的一个大佬用的左下角顶点,故我也用左下角。根据这个位置点在画布上再画出完整的方块,画图顺序按照3中所述就完事儿了。
注:这里比较重要的是计算画布的大小以及计算方块左下角在画布上的坐标(x,y),我没怎么仔细观察立体图,直接用了我看的博主的计算公式(虽然这样很不对,但是我懒啊^^丿)。
代码如下:
#include <stdio.h>
#include <string.h>
int array[51][51];
const char block[6][8]=
{
"..+---+",
"./ /|",
"+---+ |",
"| | +",
"| |/.",
"+---+.."
};//单个方块
char paint[1000][1000]; //画布
void draw(int x,int y)
{
int i,j;
for(i = 0;i < 6;i ++)
{
for(j = 0;j < 7;j ++)
{
if(block[6-i-1][j] != '.')
{
paint[x-i][y+j] = block[6-i-1][j];//这里好好体会一下这个等式关系
}
}
}
} //在画布上放置方块
int MAX(int max,int b)
{
if(max < b) max = b;
return max;
}//求最大值函数
int main()
{
int i,j,N,M;
scanf("%d%d",&N,&M);
int max = 0;
for(i = 1;i <= N;i ++)
{
for(j = 1;j <= M;j ++)
{
scanf("%d",&array[i][j]);
max = MAX(max,array[i][j]*3+2*(N-i+1)+1);//通过输入的a[i][j]计算画布纵向的最大长度,观察图就完事儿了,其实我之前自己观察的公式,但是很遗憾不对,就直接copy了大佬的
}
}
int L = 4*M+2*N+1; //画布宽度(横向),这个公式有手就行。。。。
int H = max; //画布长度(纵向)
memset(paint,'.',sizeof(char)*1000000);//画布初始化
for(i = 1;i <= N;i ++)
{
for(j = 1;j <= M;j ++)
{
int x = H-2*(N-i);//计算x坐标
int y = 2*(N-i)+4*(j-1)+1;//计算y坐标,特别注意x坐标其实是指的纵向而y坐标指的是横向
while(array[i][j]--)
{
draw(x,y);
x-=3;//从下往上叠
}
}//从左往右叠
}//从后往前叠
for(i = 1;i <= H;i ++)
{
for(j = 1;j <= L;j ++)
{
printf("%c",paint[i][j]);
}
printf("\n");
}//输出
return 0;
}
这个作业题我不是很会,大量借鉴他人代码,我主要是想写个分析增加自己记忆,看到的朋友勿怪。