分析:非常好的记忆化搜索题目。非常经典的地方就是巧妙地记录了是否有地方连续7天没有下雨,直接用四个顶点表示是否有没有下雨的地方,用一个六维的数组进行判重,并且用到了位运算和二进制进行状态表示。非常好。
代码:
const
nx:array[1..9] of integer=(0,-1,-2,0,0,1,2,0,0);
ny:array[1..9] of integer=(0,0,0,-1,-2,0,0,1,2);
type
ji=record
a,b,c,d:longint;
end;
var
d:array[0..366] of longint;
i,j,k,n:longint;
now:ji;
v:array[0..7,0..7,0..7,0..7,0..9,0..366] of boolean;
function ok(x,y,day:longint; now:ji):boolean;
var
i:longint;
begin
with now do
begin
if a=7 then exit(false);
if b=7 then exit(false);
if c=7 then exit(false);
if d=7 then exit(false);
end;
i:=(1<<(15-4*x-y))or(1<<(14-4*x-y))or(1<<(11-4*x-y))or(1<<(10-4*x-y));
if i and d[day]<>0 then exit(false);
with now do
begin
if v[a,b,c,d,3*x+y,day] then exit(false);
v[a,b,c,d,3*x+y,day]:=true;
exit(true);
end;
end;
function dfs(x,y,day:longint; now:ji):boolean;
var
i,s,t:longint;
dd:ji;
begin
if day=n then exit(true);
if not ok(x,y,day,now) then exit(false);
for i:=1 to 9 do
begin
s:=x+nx[i];
t:=y+ny[i];
if (s<0)or(t<0)or(s>2)or(t>2) then continue;
dd:=now;
with dd do
begin
inc(a);
if (s=0)and(t=0) then a:=0;
inc(b);
if (s=0)and(t=2) then b:=0;
inc(c);
if (s=2)and(t=0) then c:=0;
inc(d);
if (s=2)and(t=2) then d:=0;
end;
if dfs(s,t,day+1,dd) then exit(true);
end;
exit(false);
end;
begin
readln(n);
while n<>0 do
begin
fillchar(v,sizeof(v),0);
fillchar(d,sizeof(d),0);
for i:=0 to n-1 do
begin
for j:=0 to 15 do
begin
read(k);
d[i]:=(d[i]<<1)or k;
end;
end;
now.a:=1; now.b:=1; now.c:=1; now.d:=1;
if dfs(1,1,0,now) then writeln(1)
else writeln(0);
readln(n);
end;
end.