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.

  

你可能感兴趣的:(cast)