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

327人阅读 评论(0)

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.

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：8175次
• 积分：501
• 等级：
• 排名：千里之外
• 原创：41篇
• 转载：5篇
• 译文：0篇
• 评论：3条
阅读排行
最新评论