# 用二进制优化常数卡过Pku3074 Sudoku

const
w:array[0..8,0..8]of longint=((0,0,0,1,1,1,2,2,2),
(0,0,0,1,1,1,2,2,2),
(0,0,0,1,1,1,2,2,2),
(3,3,3,4,4,4,5,5,5),
(3,3,3,4,4,4,5,5,5),
(3,3,3,4,4,4,5,5,5),
(6,6,6,7,7,7,8,8,8),
(6,6,6,7,7,7,8,8,8),
(6,6,6,7,7,7,8,8,8));
var
bb,aa:array[0..512]of longint;
a:array[0..8,0..8]of longint;
h,l,kui:array[0..8]of longint;
now,minn,x,y,ans,n,m,i,j,k:longint;
s:string;

procedure dfs(x,y:longint);
var
ii,jj,xx,yy,minn,i,j,k:longint;
begin
if (a[x,y]<>-1) then
begin
ans:=1;
exit;
end;
i:=1;
j:=l[y] or h[x] or kui[w[x,y]];
if j=511 then
exit;
while i<512 do
begin
if j or i<>j then
begin
l[y]:=l[y] or i;
h[x]:=h[x] or i;
kui[w[x,y]]:=kui[w[x,y]]or i;
a[x,y]:=bb[i];
minn:=16;
xx:=0;yy:=0;
ii:=0;
while ii<=8 do
begin
for jj:=0 to 8 do
if a[ii,jj]=-1 then
begin
k:=l[jj] or h[ii] or kui[w[ii,jj]];
if aa[k]<minn then
begin
minn:=aa[k];
xx:=ii; yy:=jj;
end;
if minn=1 then
begin
ii:=9;
break;
end;
end;
inc(ii);
end;
dfs(xx,yy);
if ans<>0 then
exit;
l[y]:=l[y] and (not i);
h[x]:=h[x] and (not i);
kui[w[x,y]]:=kui[w[x,y]] and (not i);
end;
i:=i<<1;
end;
a[x,y]:=-1;
end;

begin
bb[1]:=0; bb[2]:=1; bb[4]:=2; bb[8]:=3; bb[16]:=4;
bb[32]:=5; bb[64]:=6; bb[128]:=7;bb[256]:=8;
for k:=0 to 512 do
begin
now:=0;
if k or 1<>k then
inc(now);
if k or 2<>k then
inc(now);
if k or 4<>k then
inc(now);
if k or 8<>k then
inc(now);
if k or 16<>k then
inc(now);
if k or 32<>k then
inc(now);
if k or 64<>k then
inc(now);
if k or 128<>k then
inc(now);
if k or 256<>k then
inc(now);
aa[k]:=now;
end;
while not eof do
begin
fillchar(h,sizeof(h),0);
fillchar(l,sizeof(l),0);
fillchar(kui,sizeof(kui),0);
fillchar(a,sizeof(a),\$ff);
if s[1]='e' then
break;
for i:=0 to 80 do
if  s[i+1]<>'.' then
begin
j:=ord(s[i+1])-ord('1');
a[i div 9,i mod 9]:=j;
h[i div 9]:=h[i div 9] or (1<<j);
l[i mod 9]:=l[i mod 9] or (1<<j);
kui[w[i div 9,i mod 9]]:=kui[w[i div 9,i mod 9]] or(1<<j);
end;
minn:=16;
i:=0;
while i<=8 do
begin
for j:=0 to 8 do
if a[i,j]=-1 then
begin
k:=l[j] or h[i] or kui[w[i,j]];
if aa[k]<minn then
begin
minn:=aa[k];
x:=i; y:=j;
end;
if minn=1 then
begin
i:=9;
break;
end;
end;
inc(i);
end;
dfs(x,y);
for i:=0 to 8 do
begin
for j:=0 to 8 do
write(a[i,j]+1);
end;
writeln;
end;
end.

• 本文已收录于以下专栏：

举报原因： 您举报文章：用二进制优化常数卡过Pku3074 Sudoku 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)