数独计算器是怎么编出来的 - 爱问答

(爱问答)

数独计算器是怎么编出来的

空位用空格补齐(每用下划线)
可以文件输入(用编译好的程序打开文件),亦可键盘输入。
用打过CRT补丁的Turbo Pascal编译,或使用Free Pascal(这个不保证正常)
样例没有超时,但对于特殊数据可能超时(我还没有数据,自己写得太简单,但是,特殊数据基本不会不超过0.01s)

程序如下:

program sdjsq;{数独解算器}
{-------------调用库------------------------------------------------USES}
uses CRT,Dos;{使用CRT Dos库}
{-------------数据类型定义------------------------------------------TYPE}
type
sz=0..9;{数字,byte类型的子界占一byte}
sy=1..9;{same as sz}
sd=array [sy,sy] of sz;{数独,占8×8×1byte=81byte}
ss=set of sy;{数字的集合}
dot=
record
s:ss;
n,x,y:byte;
end;
{-------------变量定义-----------------------------------------------VAR}
var
a:sd;
x,y:byte;
list:record
num:byte;
dat:array [1..81] of dot;
end;
{=============打印边框============================================PRINTK}
procedure printk;
var
i, k : byte;
flag : boolean;
begin
gotoxy(1,1);textcolor(15);textbackground(0);
write(#218);for k:=1 to 8 do write(#196#194);writeln(#196#191);
for i := 1 to 9 do begin
write(#179);for k:=1 to 9 do begin
textbackground(1-ord(((i-1) div 3+(k-1) div 3) mod 2=0));
write(#32);textbackground(0);write(#179);
end;
writeln;
if i<>9 then begin
write(#195);for k:=1 to 8 do write(#196#197);writeln(#196#180);
end;
end;
write(#192);for k:=1 to 8 do write(#196#193);writeln(#196#217);
gotoxy(1,1);
end;
{=============可以填的数==============================================KY}
procedure ky(a:sd;x,y:byte;var s:ss);
var
i,j:byte;
begin
s:=[1,2,3,4,5,6,7,8,9];
for i:=1 to 9 do if i<>x then s:=s-[a[i,y]];
for i:=1 to 9 do if i<>y then s:=s-[a[x,i]];
for i:=1 to 3 do for j:=1 to 3 do
if ((x-1)div 3*3+i<>x) and ((y-1)div 3*3+j<>y)
then s:=s-[a[(x-1)div 3*3+i,(y-1)div 3*3+j]];
s:=s-[0];
end;
{=============打印数据=============================================PRINT}
procedure print(xn,yn,color:byte);
begin
gotoxy(2*xn,2*yn);
textcolor(color);
textbackground(5+ord(not ((x=xn)and(y=yn)))*(-4-ord(((xn-1) div 3+(yn-1) div 3) mod 2=0)));
if a[xn,yn]<>0 then write(a[xn,yn]) else write(#32);
gotoxy(1,1);
end;
{=============用键盘读入数据===========================INPUT BY KEYBOARD}
procedure inputbkb(var a:sd);
label 1;
var
xi,yi:byte;
c:char;
s:ss;i:byte;
begin
printk;
fillchar(a,sizeof(a),0);x:=1;y:=1;print(1,1,0);
textcolor(15);textbackground(0);
s:=[1..9];gotoxy(1,20);for i:=1 to 9 do write(i:2);
repeat
c:=readkey;
xi:=x;yi:=y;
case c of
(*#13{Enter}, #27{Esc}*)
#27:halt;
(*#72{Up}, #75{Left}, #77{Right}, #80{Down}*)
#0:begin
c:=readkey;
case c of
#75:if x<>1 then x:=x-1 else write(' ');
#72:if y<>1 then y:=y-1 else write(' ');
#80:if y<>9 then y:=y+1 else write(' ');
#77:if x<>9 then x:=x+1 else write(' ');
#83:a[x,y]:=0;
end;
end;
#48..#58:if (ord(c)-48 in s) or (c=#48)
then a[x,y]:=ord(c)-48 else write(' ');
end;
print(xi,yi,12);print(x,y,12);
ky(a,x,y,s);
gotoxy(1,20);
textcolor(15);textbackground(0);delline;
for i:=1 to 9 do if i in s then write(i:2);
until c=#13;
x:=0;y:=0;print(xi,yi,12);
end;
procedure noans;
begin
gotoxy(1,20);
textbackground(0);delline;textcolor(143);
write('No answer!');
readkey;
halt;
end;
{=============用文件读入数据===============================INPUT BY FILE}
procedure inputbf(var a:sd;const path:string);
function Exist(Path:string):boolean;
var
S: PathStr;
begin
S := FSearch(Path, GetEnv(''));
Exist := S <> '';
end;
var
x,y:byte;
c:char;
f:text;
begin
if not exist(path) then begin
inputbkb(a);
end else begin
assign(f,path);reset(f);printk;
for y:=1 to 9 do begin
for x:=1 to 9 do begin
read(f,c);
if not (c in [#48..#58,#32]) then begin
inputbkb(a);exit;
end;
if c=#32 then a[x,y]:=0 else a[x,y]:=ord(c)-48;print(x,y,12);
end;
readln(f);
end;
end;
end;
{=============填入固定数据============================================TC}
procedure tc;
var
x,y,i,t,n,f:byte;
s:ss;
function tct:byte;
var
i,j,k,l:byte;
s1,s2,s3:ss;
n1,n2,n3:array [1..9] of byte;
begin
tct:=0;
for i:=1 to 9 do begin
fillchar(n1,sizeof(n1),0);fillchar(n3,sizeof(n3),0);fillchar(n2,sizeof(n2),0);
for j:=1 to 9 do begin
ky(a,i,j,s);if a[i,j]<>0 then begin s:=[a[i,j]]; n1[a[i,j]]:=10; end;
for k:=1 to 9 do if k in s then if n1[k]=0 then n1[k]:=j else n1[k]:=10;
ky(a,j,i,s);if a[j,i]<>0 then begin s:=[a[j,i]]; n2[a[j,i]]:=10; end;
for k:=1 to 9 do if k in s then if n2[k]=0 then n2[k]:=j else n2[k]:=10;
ky(a,((i-1) mod 3)*3+((j-1) mod 3+1),((i-1) div 3)*3+((j-1) div 3+1),s);
if a[((i-1) mod 3)*3+((j-1) mod 3+1),((i-1) div 3)*3+((j-1) div 3+1)]<>0 then begin
s:=[a[((i-1) mod 3)*3+((j-1) mod 3+1),((i-1) div 3)*3+((j-1) div 3+1)]];
n3[a[((i-1) mod 3)*3+((j-1) mod 3+1),((i-1) div 3)*3+((j-1) div 3+1)]]:=10;
end;
for k:=1 to 9 do if k in s then if n3[k]=0 then n3[k]:=j else n3[k]:=10;
end;
for k:=1 to 9 do begin
j:=n1[k];
if j in [1..9] then begin
a[i,j]:=k;print(i,j,6);tct:=1;exit;
end;
end;
for k:=1 to 9 do begin
j:=n2[k];
if j in [1..9] then begin
a[j,i]:=k;print(j,i,6);tct:=1;exit;
end;
end;
for k:=1 to 9 do begin
j:=n3[k];
if j in [1..9] then begin
a[((i-1) mod 3)*3+((j-1) mod 3+1),((i-1) div 3)*3+((j-1) div 3+1)]:=k;
print(((i-1) mod 3)*3+((j-1) mod 3+1),((i-1) div 3)*3+((j-1) div 3+1),6);
tct:=1;exit;
end;
end;
end;
end;
procedure check;
var
i,j,k:byte;
s,s1,s2,s3:ss;
begin
for i:=1 to 9 do begin
s1:=[];s2:=[];s3:=[];
for j:=1 to 9 do begin
if a[i,j]=0 then begin ky(a,i,j,s);s1:=s1+s; end else s1:=s1+[a[i,j]];
if a[j,i]=0 then begin ky(a,j,i,s);s2:=s2+s; end else s2:=s2+[a[j,i]];
if a[((i-1) mod 3)*3+((j-1) mod 3+1),((i-1) div 3)*3+((j-1) div 3+1)]=0 then begin
ky(a,((i-1) mod 3)*3+((j-1) mod 3+1),((i-1) div 3)*3+((j-1) div 3+1),s);s3:=s3+s;
end else s3:=s3+[a[((i-1) mod 3)*3+((j-1) mod 3+1),((i-1) div 3)*3+((j-1) div 3+1)]];
end;
for j:=1 to 9 do begin
if not (j in s1) then noans;
if not (j in s2) then noans;
if not (j in s3) then noans;
end;
end;
end;
begin
repeat
f:=0;
for x:=1 to 9 do
for y:=1 to 9 do
if a[x,y]=0 then begin
ky(a,x,y,s);t:=0;
if s=[] then
noans;
for i:=1 to 9 do if i in s then begin
t:=t+1;n:=i;
end;
if t=1 then begin a[x,y]:=n;print(x,y,14);f:=f+1; end;
end;
f:=f+tct;check;
until f=0;
end;
{=============递归求解===============================================TRY}
function answer:boolean;
var
ans:boolean;
procedure try(num:byte);
var
i,j,n,x,y:byte;
s:ss;
begin
if keypressed then case readkey of #27:halt;#0:if readkey=#107 then halt; end;
if num<=list.num then begin
x:=list.dat[num].x;y:=list.dat[num].y;
ky(a,x,y,s);if s=[] then exit;
n:=random(8)+1;
for j:=n to n+8 do begin
i:=j mod 9+1;
if i in s then begin
a[x,y]:=i;print(x,y,10);
try(num+1);
a[x,y]:=0;print(x,y,0)
end
end
end else begin
gotoxy(1,20);textcolor(15);textbackground(0);delline;write('Complete! ');answer:=true;ans:=true;
case readkey of #27:halt;#0:if readkey=#107 then halt; end;
textcolor(15);textbackground(0);gotoxy(1,20);delline;writeln('Trying...');
end;
end;
begin
answer:=false;ans:=false;
try(1)
end;
procedure crtinit;
var
OrigMode: word;
begin
OrigMode:=LastMode; { Remember original video mode }
TextMode(Lo(LastMode)+Font8x8); { use 43 or 50 lines on EGA/VGA }
end;
procedure px;
var
l:array [1..9] of record
num:byte;
dat:array [1..81] of dot;
end;
i,j,k:byte;
d:dot;
begin
for i:=1 to 9 do l[i].num:=0;
for i:=1 to 9 do for j:=1 to 9 do if a[i,j]=0 then begin
d.x:=i;d.y:=j;ky(a,i,j,d.s);d.n:=0;for k:=1 to 9 do if k in d.s then inc(d.n);
inc(l[d.n].num);l[d.n].dat[l[d.n].num]:=d;
end;
list.num:=0;
for i:=1 to 9 do for j:=1 to l[i].num do begin
inc(list.num);list.dat[list.num]:=l[i].dat[j];
end;
end;
begin
randomize;
crtinit;
textbackground(0);clrscr;
if ParamCount=0 then inputbkb(a) else inputbf(a,ParamStr(1));
textcolor(15);textbackground(0);gotoxy(1,20);delline;writeln('Thinking...');tc;
textcolor(15);textbackground(0);gotoxy(1,20);delline;writeln('Checking...');px;
textcolor(15);textbackground(0);gotoxy(1,20);delline;writeln('Trying...');gotoxy(1,1);
if not answer then noans;
textcolor(15);textbackground(0);gotoxy(1,20);delline;writeln('That''s all!');readkey;
end.

相关标签:数独

下一篇:数独游戏,在每一个小九格中,分别填上1-9的数字让整个大九宫格每一行每一列数

上一篇:数独游戏9个3x3的方格

热门标签:
我的世界 LOL 绝地求生 王者荣耀 吃鸡 英雄联盟 GTA 荒野行动 使命召唤 穿越火线 魔兽世界 网游 植物大战僵尸 造梦西游 逆战 排位 qq飞车 阴阳师 楚留香 斗地主 坦克世界 守望先锋 星际战甲 蜀门手游 300英雄
最新更新:
原神恢复如初解密-原神恢复如初任务攻略 原神万叶配队-原神万叶阵容搭配 原神4.0水主命座-原神4.0水主技能 原神娜维娅武器-原神娜维娅技能怎么用 原神芙卡洛斯水神什么时候出-原神芙卡洛斯水神命座 原神角色强度排行-原神林尼等级突破材料 原神角色强度排行-原神林尼天赋材料 原神fes在哪里买票-原神fes什么时候开票 原神林尼值得抽吗-原神林尼技能介绍 原神4.1版本什么时候上线-原神4.1版本是几月几号 光遇有友节任务怎么做-光遇有友节任务攻略 逆水寒手游一曲阳关怎么做-逆水寒手游一曲阳关任务 逆水寒手游宋辽贺俊杰任务怎么做-逆水寒手游宋辽贺俊杰任务攻略 逆水寒春山笑奇遇攻略-逆水寒春山笑奇遇触发不了 逆水寒手游金镯疑案攻略-逆水寒手游攻略