1. 程式人生 > >2018.10.1 2018NOIP衝刺之立體圖

2018.10.1 2018NOIP衝刺之立體圖

圖不是很清楚 下面有

【輸入】

輸入檔案 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('\n');
    }
    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;
}