今天很闲,整理一下最近写的很有代表性的题目,拿出来晒晒,勿喷、勿喷呃……
去年刚刚看到这个题目,愣是没有想出什么办法来,只感觉是个纯数学题,限于水平没有敢写。今年又翻出来看,结果想到了一个简单的办法(再次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.