分析:直接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.