靶型数独
一看就是搜索,DFS,
顺着搜卡时过了80分,
倒着搜卡时竟然全过了,
只能说数据比较合适倒着搜,貌似总是倒着搜要好一点——不知道为什么额。
有说用dancing links 的,但是不会,现在就去学
虽然是用不能AC的程序AC了,但还是贴出来。
除了3个布尔数组,实在也想不到什么能都剪枝的了。
const
v:array[1..9,1..9]of longint=
(
(6,6,6,6,6,6,6,6,6),
(6,7,7,7,7,7,7,7,6),
(6,7,8,8,8,8,8,7,6),
(6,7,8,9,9,9,8,7,6),
(6,7,8,9,10,9,8,7,6),
(6,7,8,9,9,9,8,7,6),
(6,7,8,8,8,8,8,7,6),
(6,7,7,7,7,7,7,7,6),
(6,6,6,6,6,6,6,6,6));
pa:array[1..9,1..9]of longint=
(
(1,1,1,2,2,2,3,3,3),
(1,1,1,2,2,2,3,3,3),
(1,1,1,2,2,2,3,3,3),
(4,4,4,5,5,5,6,6,6),
(4,4,4,5,5,5,6,6,6),
(4,4,4,5,5,5,6,6,6),
(7,7,7,8,8,8,9,9,9),
(7,7,7,8,8,8,9,9,9),
(7,7,7,8,8,8,9,9,9)
);
var
fa,fy,fx:array[1..9,1..9]of boolean;
i,j,lc,ans,yuan,ks:longint;
m:array[1..9,1..9]of longint;
lx,ly:array[1..81]of longint;
procedure dfs(t:longint);
var
i,j,x,y,tem:longint;
begin
inc(ks);
if ks=10000000 then begin
writeln(ans);
halt;
end;
//write(t);
if t=0 then begin
tem:=yuan;
for i:=1 to lc do tem:=v[lx[i],ly[i]]*m[lx[i],ly[i]]+tem;
if tem>ans then ans:=tem;
exit;
end;
x:=lx[t];
y:=ly[t];
for i:=1 to 9 do
if fa[i,pa[x,y]] and fx[i,x] and fy[i,y]then begin
fa[i,pa[x,y]]:=false;
fx[i,x]:=false;
fy[i,y]:=false;
m[x,y]:=i;
dfs(t-1);
fa[i,pa[x,y]]:=true;
fx[i,x]:=true;
fy[i,y]:=true;
end;
end;
begin
fillchar(fx,sizeof(fx),true);
fillchar(fy,sizeof(fy),true);
fillchar(fa,sizeof(fa),true);
ks:=0;
lc:=0;
ans:=-1;
yuan:=0;
for i:=1 to 9 do
for j:=1 to 9 do begin
read(m[i,j]);
if m[i,j]=0 then begin
inc(lc);
lx[lc]:=i;
ly[lc]:=j;
end else begin
fa[m[i,j],pa[i,j]]:=false;
fx[m[i,j],i]:=false;
fy[m[i,j],j]:=false;
yuan:=yuan+m[i,j]*v[i,j];
end;
end;
dfs(lc);
writeln(ans);
end.