MY*****

poj 2676 soduku

分析:直接dfs即可,没什么。只不过从1,1开始搜时间是1000++,从n,n开始搜时间是16ms。差距。所以最好的办法就是随机搜索。

poj上另外的两个soduku就不是简单的搜索能通过的了,3074的很多数据单个都不能很快出结果,对3076更慢,只能用dancing links来优化或者彻底改变搜索方式+加上强剪枝。

代码:

var
  z,h,l:array[1..9,1..9] of boolean;
  a:array[1..9,1..9] of integer;
  b:array[1..9,1..9] of integer;
  t,i,j,k:longint;
  ch:char;
  vv:boolean;

procedure dfs(x,y:longint);
var
  v:array[1..9] of boolean;
  stack:array[1..9] of integer;
  step,j,i,k:longint;
begin
  if vv then exit;
  if (x=1)and(y=1)and(a[x,y]<>0) then
    begin
      for i:=1 to 9 do
        begin
          for j:=1 to 9 do
            write(a[i,j]);
          writeln;
        end;
      vv:=true;
      exit;
    end;
  if y<1 then
    begin
      x:=x-1;
      y:=9;
      if x<1 then
        begin
          for i:=1 to 9 do
            begin
              for j:=1 to 9 do
                write(a[i,j]);
              writeln;
            end;
          vv:=true;
          exit;
        end;
    end;
  if a[x,y]<>0 then
    begin
      if y=1 then dfs(x-1,9)
      else dfs(x,y-1);
      if vv then exit;
    end
  else
    begin
      k:=b[x,y];
      step:=0;
      for i:=1 to 9 do
        begin
          v[i]:=false;
          if l[y,i]=true then v[i]:=true;
          if h[x,i]=true then v[i]:=true;
          if z[k,i]=true then v[i]:=true;
          if not v[i] then
            begin
              inc(step);
              stack[step]:=i;
            end;
        end;
      for j:=1 to step do
        begin
          i:=stack[j];
          a[x,y]:=i;
          l[y,i]:=true;
          h[x,i]:=true;
          z[k,i]:=true;
          dfs(x,y-1);
          if vv then exit;
          z[k,i]:=false;
          h[x,i]:=false;
          l[y,i]:=false;
          a[x,y]:=0;
        end;
    end;
end;

begin
  readln(t);
  for i:=1 to 9 do
    for j:=1 to 9 do
      begin
        if (i<=3)and(j<=3) then b[i,j]:=1 else
        if (i<=3)and(j<=6) then b[i,j]:=2 else
        if (i<=3)and(j<=9) then b[i,j]:=3 else
        if (i<=6)and(j<=3) then b[i,j]:=4 else
        if (i<=6)and(j<=6) then b[i,j]:=5 else
        if (i<=6)and(j<=9) then b[i,j]:=6 else
        if (i<=9)and(j<=3) then b[i,j]:=7 else
        if (i<=9)and(j<=6) then b[i,j]:=8 else
        if (i<=9)and(j<=9) then b[i,j]:=9;
      end;
  while t>0 do
    begin
      dec(t);
      vv:=false;
      fillchar(z,sizeof(z),0);
      fillchar(h,sizeof(h),0);
      fillchar(l,sizeof(l),0);
      fillchar(a,sizeof(a),0);
      for i:=1 to 9 do
        begin
          for j:=1 to 9 do
            begin
              k:=b[i,j];
              read(ch);
              a[i,j]:=ord(ch)-48;
              if a[i,j]=0 then continue;
              l[j,a[i,j]]:=true;
              h[i,a[i,j]]:=true;
              z[k,a[i,j]]:=true;
            end;
          readln;
        end;
      dfs(9,9);
    end;
end.

  

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

导航