MY*****

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.

  

posted on 2011-10-20 07:52  reflec94  阅读(292)  评论(0编辑  收藏  举报

导航