luogu P1058 立体图

本文介绍了一种用于绘制复杂图案的算法,通过预先准备好的方块和画布,按特定顺序绘制实现新图案的遮挡效果,解决了硬写难以实现的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题解

可以说是很烦的题目了。硬写是基本做不到的,存在遮挡的问题,人肉考虑无比繁琐,反正我是放弃了。
可行的做法是,准备好一个健全的方块,以及一个画布 (char canvas[][] ),然后一个一个画上去copy。
亮点是如果按照一定顺序画的话,后画的能恰好实现遮挡前面的。是不是很巧。


Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;

int n,m,MH=0;
char canvas[1000][1000];
int maze[101][101];
string pc[]={
"  +---+",
" /   /|",
"+---+ |",
"|   | +",
"|   |/ ",
"+---+  "
};

void draw(int x,int y){// draw a square
    int xx=x,yy=y-1;
    for(int i=5;i>=0;i--){
        for(int j=0;j<7;j++){
            yy++;
            if(i!=2 && i!=3){ // don't draw the space
                if(i==0 &&(j==0||j==1)) continue;
                if(i==1&& j==0) continue;
                if(i==4 && j==6) continue;
                if(i==5 &&(j==6||j==5)) continue;
            }
            canvas[xx][yy]=pc[i][j];
        }
        xx++;
        yy=y-1;
    }
}

void drawM(int mh){// mh equals the max value of matrix
    int x,y,initx,inity;
    x = initx = (n-1)*2;
    y = inity = x;

    for(int k=1;k<=mh;k++){ // from buttom to head
        for(int i=1;i<=n;i++){ // from inside to outside
            for(int j=1;j<=m;j++){ // from left to right
                if( maze[i][j]>=k){
                    //cout<<x<<" "<<y<<endl;
                    draw(x,y);
                    if(x+5 > MH) MH = x+5;// highest row in canvas
                }
                y+=4;
            }
            x-=2;
            y= inity-2*i;
        }
        x=initx+3*k;
        y=inity;
    }

}

void init(){
    memset(canvas,'.',sizeof(canvas));
}
void pr(int mh){
    for(int i=mh;i>=0;i--){// h is not absolute, calc by drawM()
        for(int j=0;j<4*m+2*n+1;j++)// w is absolute
            cout<<canvas[i][j];
        cout<<endl;
    }
}

int main(){
    cin>>n>>m;
    int hh=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            cin>>maze[i][j];
            hh = max(hh,maze[i][j]);
        }
    init();
    drawM(hh);
    pr(MH);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值