讨论 / 按年鉴上的优化写的,次数卡150W能过19组……求较好的次数……
fts96 2012-10-06 02:35:00
点我顶贴 收藏 删除
program rq521;

const

fen: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));

var

pu,co:array[1..9,1..9] of longint;

xz,shu:array[1..81] of longint;

orx,ory:array[1..81] of longint;

p,z,ans,mans,j,k,l,ci:longint;

t:array[1..81,0..20] of longint;

flag:array[1..81] of boolean;

boo:boolean;

procedure add_edge(a,b:longint);

begin

inc(t[a][0]);

t[a][t[a][0]]:=b;

end;

procedure init;

var i,j,k,l,m,n,c:longint;

mx,my,min:longint;

begin

z:=0;

fillchar(t,sizeof(t),0);

c:=0;

for i:=1 to 9 do

for j:=1 to 9 do

begin

inc(c);

read(pu[i][j]);

co[i][j]:=c;

shu[c]:=pu[i][j];

if pu[i][j]<>0 then inc(mans,pu[i][j]*fen[i][j]);

end;

for i:=1 to 9 do

for j:=1 to 8 do

for k:=j+1 to 9 do

if ((j+2) div 3)<>((k+2) div 3) then

begin

add_edge(co[i][j],co[i][k]);

add_edge(co[i][k],co[i][j]);

end;

for i:=1 to 9 do

for j:=1 to 8 do

for k:=j+1 to 9 do

if ((j+2) div 3)<>((k+2) div 3) then

begin

add_edge(co[j][i],co[k][i]);

add_edge(co[k][i],co[j][i]);

end;

for i:=0 to 2 do

for j:=0 to 2 do

for k:=1 to 3 do

for l:=1 to 3 do

for m:=1 to 3 do

for n:=1 to 3 do

if (k<>m)or(l<>n) then add_edge(co[i*3+k][j*3+l],co[i*3+m][j*3+n]);

fillchar(flag,sizeof(flag),false);

fillchar(xz,sizeof(xz),0);

for i:=1 to 9 do

for j:=1 to 9 do

if pu[i][j]<>0 then flag[co[i][j]]:=true

else inc(z);

for i:=1 to 9 do

for j:=1 to 9 do

if pu[i][j]=0 then

begin

c:=co[i][j];

for k:=1 to 20 do if flag[t[c][k]] then inc(xz[co[i][j]]);

end;

for i:=1 to z do

begin

min:=0;

for j:=1 to 9 do

for k:=1 to 9 do

if (not flag[co[j][k]])and(xz[co[j][k]]>min) then

begin

min:=xz[co[j][k]];

mx:=j;

my:=k;

end;

flag[co[mx][my]]:=true;

inc(p);

orx[p]:=mx;

ory[p]:=my;

for j:=1 to 20 do inc(xz[t[co[mx][my]][j]]);

end;

end;

procedure search(x:longint);

var i,c:longint;

begin

inc(ci);

if ci>1500000 then

begin

writeln(ans);

halt;

end;

if x>z then

begin

if mans>ans then ans:=mans;

exit;

end;

c:=co[orx[x]][ory[x]];

for i:=1 to 9 do

begin

boo:=true;

for j:=1 to 20 do if shu[t[c][j]]=i then boo:=false;

if boo then

begin

shu[c]:=i;

inc(mans,i*fen[orx[x]][ory[x]]);

search(x+1);

shu[c]:=0;

dec(mans,i*fen[orx[x]][ory[x]]);

end;

end;

end;

begin

mans:=0;

init;

ans:=-1;

search(1);

writeln(ans);

end.

查看更多回复
提交回复