2018.10.1 2018NOIP冲刺之立体图

2008NOIP普及组立体图 请自行百度(事实上放不下了)

图不是很清楚 下面有

【输入】

输入文件 drawing.in 第一行有用空格隔开的 2 个整数 m 和 n,表示有 m*n  个格子

(1<=m,n<=50)。

接下来的 m 行,是一个 m*n 的矩阵,每行有 n 个用空格隔开的整数,其中第 i 行第 j 列上的整数表示第 i 行第 j 列的个子上摞有多少个积木(1<=每个格子上的积木数<=100)。【输出】

输出文件 drawing.out 中包含题目要求的立体图,是一个 K 行 L 列的字符串矩阵,其中 K 和 L 表示最少需要 K 行 L 列才能按规定输出立体图。

也就是说大概要输出这样一个图

这个图的输入是这样的:

3 4

2 2 1 2

2 2 1 1

3 2 1 2


很明显是一个大模拟的题但是依然有许多坑

第一个解决遮挡问题

为了模拟真正的遮挡我们在画图的时候就选择从后往前画并用立方体中间的空格进行覆盖

void drawb(int p,int q)
{
    map[p][q]=map[p-3][q]=map[p-5][q+2]=map[p-5][q+6]=map[p-2][q+6]=map[p][q+4]=map[p-3][q+4]='+';
    map[p][q+1]=map[p][q+2]=map[p][q+3]='-';
    map[p-3][q+1]=map[p-3][q+2]=map[p-3][q+3]='-';
    map[p-5][q+3]=map[p-5][q+4]=map[p-5][q+5]='-';
    map[p-1][q+5]=map[p-4][q+1]=map[p-4][q+5]='/';
        //
    for(int i=p-2;i<p;i++)
        for(int j=q+1;j<=q+3;j++)
            map[i][j]=' ';//覆盖部分 
    map[p-4][q+2]=map[p-4][q+3]=map[p-4][q+4]=' ';
    map[p-2][q+5]=map[p-3][q+5]=' ';
    map[p-1][q]=map[p-2][q]='|';
    map[p-1][q+4]=map[p-2][q+4]='|';
    map[p-3][q+6]=map[p-4][q+6]='|';
    return;
}

第二如何讨论最少的行和列

通过对图的观察我们不难发现:

(1)正面的底边对应一部分行

(2)侧面的底边对应另一部分行(因为侧面恰好可以对应底边)

(即maxx=4*n+1+2*m)

(3)我们对从前往后每一个截面进行讨论:

1、找到这一个截面的最高点

2、通过这个点的高度(从下往上第几层)以及位于第几个斜面(侧面必须作为讨论列的依据)找出最大值

for(int i=1;i<=m;i++)maxx=max(maxh[i]*3+1+2*(m-i+1),maxx);

到此为止这个题就做完了

上代码


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int m,n,maxh[10005],martix[100][100],maxx,maxy,x[100][100][105],y[100][100][105];
char map[1005][1005];
void drawb(int p,int q)//画一个立方体,以p,q作为左下角坐标
{
    map[p][q]=map[p-3][q]=map[p-5][q+2]=map[p-5][q+6]=map[p-2][q+6]=map[p][q+4]=map[p-3][q+4]='+';
    map[p][q+1]=map[p][q+2]=map[p][q+3]='-';
    map[p-3][q+1]=map[p-3][q+2]=map[p-3][q+3]='-';
    map[p-5][q+3]=map[p-5][q+4]=map[p-5][q+5]='-';
    map[p-1][q+5]=map[p-4][q+1]=map[p-4][q+5]='/';
    for(int i=p-2;i<p;i++)
        for(int j=q+1;j<=q+3;j++)
            map[i][j]=' ';//覆盖部分 
    map[p-4][q+2]=map[p-4][q+3]=map[p-4][q+4]=' ';
    map[p-2][q+5]=map[p-3][q+5]=' ';
    map[p-1][q]=map[p-2][q]='|';
    map[p-1][q+4]=map[p-2][q+4]='|';
    map[p-3][q+6]=map[p-4][q+6]='|';
    return;
}
void init()
{
    maxy=4*n+2*m+1;
    for(int i=1;i<=m;i++)maxx=max(maxh[i]*3+1+2*(m-i+1),maxx);
    for(int i=1;i<=maxx;i++)
    {
        for(int j=1;j<=maxy;j++)
        {
            map[i][j]='.';
        }
    }
    x[m][1][1]=maxx,y[m][1][1]=1;
    for(int i=2;i<=n;i++)x[m][i][1]=x[m][i-1][1],y[m][i][1]=y[m][i-1][1]+4;
    for(int i=1;i<=n;i++)
    {
        for(int j=m-1;j>=1;j--)
        {
            x[j][i][1]=x[j+1][i][1]-2;
            y[j][i][1]=y[j+1][i][1]+2;
        }
    }
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(int k=2;k<=martix[i][j];k++)
            {
                x[i][j][k]=x[i][j][k-1]-3;
                y[i][j][k]=y[i][j][k-1];
            }
        }
    }
    return;
}
void print()
{
    for(int i=1;i<maxx;i++)
    {
        for(int j=1;j<=maxy;j++)putchar(map[i][j]);
        putchar('
');
    }
    for(int j=1;j<=maxy;j++)putchar(map[maxx][j]);
    return;
}
int main()
{
    freopen("drawing.in","r",stdin);
    freopen("drawing.out","w",stdout);
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&martix[i][j]);
            maxh[i]=max(maxh[i],martix[i][j]);
        }
    }
    init();
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(int k=1;k<=martix[i][j];k++)
            {
                drawb(x[i][j][k],y[i][j][k]);
            }
        }
    }
    print();
    fclose(stdin);
    fclose(stdout);
    return 0;
}

---恢复内容结束---

/*====年轻人,瞎搞是出不了省一的,这就是现实====*/
原文地址:https://www.cnblogs.com/qxds/p/9734637.html