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