poj 2044 weather forcast
分析:非常好的记忆化搜索题目。非常经典的地方就是巧妙地记录了是否有地方连续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.