TYVJ P1009 [立体图]

今天很闲,整理一下最近写的很有代表性的题目,拿出来晒晒,勿喷、勿喷呃……

去年刚刚看到这个题目,愣是没有想出什么办法来,只感觉是个纯数学题,限于水平没有敢写。今年又翻出来看,结果想到了一个简单的办法(再次Orz dxh大神的纯数学方法…)

 

关于这道题目,里面的积木覆盖顺序一定是前面的挡住后面的,右边的挡住左边的,那么就可以用一个模拟放置积木的算法来画图。当然,放置的顺序是从后往前,从左往右。至于每一个积木的位置,可以由它下面的积木的位置所确定。

只要能求出最下面积木的放置位置,和整个平面图的长宽,那么这个问题就解决了。

用一个递推就可以求出每个积木的位置,注意初始位置的计算和平面图大小的计算(表示刚开始算法中把j-1写成了i交上竟然得了80分…感谢数据让我刚开始丝毫没有感觉到是算法问题,我还以为数组开小了)

[pascal 代码]

Type
        lzy=record
                x,y:longint;
        end;
Const
        struct:array[1..6]of string=('..+---+','./   /|','+---+ |','|   | +','|   |/.','+---+..');
        struct2:array[1..6]of string=('--+---+',' /   /|','+---+ |','|   | +','|   |/.','+---+..');
VAR
        map:array[-1..1000,-1..1000]of char;
        height:array[-1..1000,-1..1000]of longint;
        wz:array[-1..100,-1..100,-1..1000]of lzy;
        n,m,len,wid,h,i,j,indy,indx,hh,maxh:longint;
Procedure init;
 var
        i,j:longint;
 begin
        readln(n,m);
        maxh:=0;
        for i:=1 to n do
                begin
                        for j:=1 to m do
                                begin
                                        read(height[i,j]);
                                        if height[i,j]>maxh then maxh:=height[i,j];
                                end;
                        readln;
                end;
 end;
Procedure ready;
 var
        i,j:longint;
 begin
        len:=m*4+n*2+1;
        h:=0;
        for i:=1 to n do
                for j:=1 to m do if (i-1)*(-2)+3*height[i,j]+1>h then h:=(i-1)*(-2)+3*height[i,j]+1;
        h:=h+n*2;wid:=h;
        indy:=n*2-1;
        indx:=h-2*n-3;
        wz[1,1,1].x:=indx;
        wz[1,1,1].y:=indy;
 end;
Procedure paint(stx,sty:longint);
 var
        i,j:longint;
 begin
        for i:=stx to stx+5 do
                for j:=sty to sty+6 do
                        begin
                                if (i-stx+1=1)and((j-sty+1=1)or(j-sty+1=2))then continue;
                                if (i-stx+1=2) and (j-sty+1=1) then continue;
                                if (i-stx+1=6)and((j-sty+1=6)or(j-sty+1=7))then continue;
                                if (i-stx+1=5) and (j-sty+1=7) then continue;
                                map[i,j]:=struct[i-stx+1][j-sty+1];
                        end;
 end;
Procedure paints(stx,sty:longint);
 var
        i,j:longint;
 begin
        for i:=stx to stx+5 do
                for j:=sty to sty+6 do
                        begin
                                if (i-stx+1=1)and((j-sty+1=1)or(j-sty+1=2))then continue;
                                if (i-stx+1=2) and (j-sty+1=1) then continue;
                                if (i-stx+1=6)and((j-sty+1=6)or(j-sty+1=7))then continue;
                                if (i-stx+1=5) and (j-sty+1=7) then continue;
                                map[i,j]:=struct2[i-stx+1][j-sty+1];
                        end;
 end;
Procedure print;
 var
        i,j:longint;
 begin
        for i:=1 to wid do
                begin
                        for j:=1 to len do write(map[i,j]);
                        writeln;
                end;
 end;
Begin
        init;
        fillchar(map,sizeof(map),'.');
        ready;
        if height[1,1]>=1 then paint(indx,indy);
        {print;}
        for hh:=1 to maxh do
        begin
        if hh=1 then
        begin
        for i:=1 to n do
                for j:=1 to m do
                        begin
                                if height[i,j]<=0 then continue;
                                dec(height[i,j]);
                                if(i=1)and(j=1) then continue;
                                        begin
                                                if j<>1 then
                                                        begin
                                                                wz[i,j,1].x:=wz[i,j-1,1].x;
                                                                wz[i,j,1].y:=wz[i,j-1,1].y+4;
                                                                paints(wz[i,j,1].x,wz[i,j,1].y);
                                                        end
                                                else
                                                        begin
                                                                wz[i,j,1].y:=wz[i-1,j,1].y-2;
                                                                wz[i,j,1].x:=wz[i-1,j,1].x+2;
                                                                paint(wz[i,j,1].x,wz[i,j,1].y);
                                                        end;
                                                {print;}
                                        end;
                        end;
        end
        else
        begin
        for i:=1 to n do
                for j:=1 to m do
                        begin
                                if height[i,j]<=0 then continue;
                                dec(height[i,j]);
                                        begin
                                                wz[i,j,hh].x:=wz[i,j,hh-1].x-3;
                                                wz[i,j,hh].y:=wz[i,j,hh-1].y;
                                                paints(wz[i,j,hh].x,wz[i,j,hh].y);
                                                {print;}
                                        end;
                        end;
        end;
        end;
        print;
End.
 

转载于:https://www.cnblogs.com/FreeDestiny/archive/2011/10/25/2223302.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值