Kai’blog

技术博客

【模拟】立体图

原题传送门

思路


天啊,不愧是普及组第四题,好难啊,以蒟蒻目前的能力,完全独自的做出来还是力不从心啊,看来以后要加强练习了!!!
我现在处在一种“不看题解就懵逼,一看题解就秒会”的尴尬境界,这么说吧,我理解别人代码的能力远超过我理解我自己代码的能力QAQ......

主要方法是将单个方块的图案存下来(打表万岁),然后找到画布中每个方块的对应坐标,copy即可。
关键在于三点:

  • 摆放顺序
    显而易见,我们应当从后往前,从下往上,从左往右进行摆放,这样可以处理好遮挡的问题,因为此题的观察视角是右上方(相对于积木而言),如果本题的观察视角改变,处理的顺序也需要改变。
  • 坐标的计算
    分析完处理顺序后,我们就需要计算画布中方块的对应坐标了。这里不需要找出方块的所有坐标,只需找出某一特殊点(如顶点)即可。怎么计算呢,当然是观察法找规律了。
  • 长宽的计算
    想要计算出并输出画布,必须求出画布的长与宽,这里可以说是这道题最容易出错的地方了,必须仔细认真。

注:此代码中计算的是左下角的顶点。

Code


#include<cstdio>
#include<iostream>
using namespace std;
const char Stick[6][8]=
{
    "..+---+",
    "./   /|",
    "+---+ |",
    "|   | +",
    "|   |/.",
    "+---+.."
};
int a[55][55];
char Paint[550][550];//画布 
inline void Draw(int x,int y)//涂鸦函数 
{
    int i,j;
    for(i=0;i<6;i++)
        for(j=0;j<7;j++)
            if(Stick[6-i-1][j]!='.')
                Paint[x-i][y+j]=Stick[6-i-1][j];
}
int main()
{
    int N,M,K(0),L,i,j,x,y;
    scanf("%d%d",&N,&M);
    L=4*M+2*N+1;//计算画布宽度 
    for(i=1;i<=N;i++)
        for(j=1;j<=M;j++)
        {
            scanf("%d",&a[i][j]);
            K=max(K,a[i][j]*3+2*(N-i+1)+1);//计算画布长度 
        }
    for(i=1;i<=K;i++)
        for(j=1;j<=L;j++)
            Paint[i][j]='.';//画布初始化 
    for(i=1;i<=N;i++)    
        for(j=1;j<=M;j++)
        {
            x=K-2*(N-i);
            y=2*(N-i)+4*(j-1)+1;//计算坐标 
            while(a[i][j]--)
            {
                Draw(x,y);//涂鸦 
                x-=3;//向上放 
            }
        }
    for(i=1;i<=K;i++)
    {
        for(j=1;j<=L;j++)
            printf("%c",Paint[i][j]);
        printf("\n");
    }//打印画布 
    return 0;
}
posted @ 2019-07-27 19:53  Kai02  阅读(212)  评论(0编辑  收藏  举报
Copyright © 2019-2020 拱大垲. All rights reserved.