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.