洛谷P1058 立体图题解

纯属自己写完题后的总结,中间借鉴了很多博客的做法。
题目: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;
}

这个作业题我不是很会,大量借鉴他人代码,我主要是想写个分析增加自己记忆,看到的朋友勿怪。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值