pwxiaolongren
pwxiaolongren
采纳率50%
2015-08-21 12:50 阅读 1.9k

回溯 搜索 数独 pascal 求高手赐教

我的代码 请问那里有问题 答案总是错 谢谢

靶形数独
(sudo.pas/c/cpp)
【问题描述】
小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低。但普通的数独对他们来说都过于简单了,于是他们向Z博士请教,Z博士拿出了他最近发明的“靶形数独”,作为这两个孩子比试的题目。
靶形数独的方格同普通数独一样,在9格宽×9格高的大九宫格中有9个3格宽×3格高的小九宫格(用粗黑色线隔开的)。在这个大九宫格中,有一些数字是已知的,根据这些数字,利用逻辑推理,在其他的空格上填入1到9的数字。每个数字在每个小九宫格内不能重复出现,每个数字在每行、每列也不能重复出现。但靶形数独有一点和普通数独不同,即每一个方格都有一个分值,而且如同一个靶子一样,离中心越近则分值越高。(如图)

                           (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)

上图具体的分值分布是:最里面一格(黄色区域)为10分,黄色区域外面的一圈(红色区域)每个格子为9分,再外面一圈(蓝色区域)每个格子为8分,蓝色区域外面一圈(棕色区域)每个格子为7分,最外面一圈(白色区域)每个格子为6分,如上图所示。比赛的要求是:每个人必须完成一个给定的数独(每个给定数独有可能有不同的填法),而且要争取更高的总分数。而这个总分数即每个方格上的分值和完成这个数独时填在相应格上的数字的乘积的总和。如图,在以下这个已经填完数字的靶形数独游戏中,总分为2829。游戏规定,将以总分数的高低决出胜负。

7 5 4 9 3 8 2 6 1
1 2 8 6 4 5 9 3 7
6 3 9 2 1 7 4 8 5
8 6 5 4 2 9 1 7 3
9 7 2 3 5 1 6 4 8
4 1 3 8 7 6 5 2 9
5 4 7 1 8 2 3 9 6
2 9 1 7 6 3 8 5 4
3 8 6 5 9 4 7 1 2

由于求胜心切,小城找到了善于编程的你,让你帮他求出,对于给定的靶形数独,能够得到的最高分数。

【输入】
输入文件名为sudo.in。
一共9行,每行9个整数(每个数都在0—9的范围内),表示一个尚未填满的数独方格,未填满的空格用“0”表示。每两个数字之间用一个空格隔开。

【输出】
输出文件sudo.out共1行。
输出可以得到的靶形数独的最高分数。如果这个数独无解,则输出整数-1。

【输入输出样例1】
sudo.in sudo.out
7 0 0 9 0 0 0 0 1
1 0 0 0 0 5 9 0 0
0 0 0 2 0 0 0 8 0
0 0 5 0 2 0 0 0 3
0 0 0 0 0 0 6 4 8
4 1 3 0 0 0 0 0 0
0 0 7 0 0 2 0 9 0
2 0 1 0 6 0 8 0 4
0 8 0 5 0 4 0 1 2 2829

【输入输出样例2】
sudoku.in sudoku.out
0 0 0 7 0 2 4 5 3
9 0 0 0 0 8 0 0 0
7 4 0 0 0 5 0 1 0
1 9 5 0 8 0 0 0 0
0 7 0 0 0 0 0 2 5
0 3 0 5 7 9 1 0 8
0 0 0 6 0 1 0 0 0
0 6 0 9 0 0 0 0 1
0 0 0 0 0 0 0 0 6 2852

【数据范围】
40%的数据,数独中非0数的个数不少于30。
80%的数据,数独中非0数的个数不少于26。
100%的数据,数独中非0数的个数不少于24。
每个测试点时限:2秒
内存上限:128M

program shudu;
type lin=set of 0..9;
type pos=
record
x,y:longint;
end;
const gong: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));
qvan: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 i,j,kcz,max,hg,dg:longint;
ji:set of 0..9;
used:array[1..90]of boolean;
map:array[0..10,0..10]of longint;
dot:array[0..81]of pos;
fh:array[0..9,0..9]of boolean;
fl:array[0..9,0..9]of boolean;
fj:array[0..9,0..9]of boolean;
function ysgs(se:lin):longint;
var i,k:longint;
begin
k:=0;
for i:=1 to 9 do
if i in se then inc(k);
exit(k);
end;
function zsfa:longint;
var i,j,k,min,g:longint;
begin
min:=1000;
g:=0;
k:=0;
for i:=1 to kcz do
if not used[i] then
begin
ji:=[1..9];
for j:=1 to 9 do
begin
if (not fh[dot[i].x,j])or(not fl[dot[i].y,j])or(not fj[gong[dot[i].x,dot[i].y],j])then ji:=ji-[j];
end;
k:=ysgs(ji);
if k end;
exit(g);
end;
procedure cl;
var i,k:longint;
begin
k:=0;
for i:=1 to kcz do
k:=k+map[dot[i].x,dot[i].y]*qvan[dot[i].x,dot[i].y];
if k>max then max:=k;
end;
procedure dfs(s:longint);
var i:longint;
begin
if s=0 then dfs(zsfa)
else
begin
inc(dg);
for i:=1 to 9 do
begin
if fh[dot[s].x,i]and fl[dot[s].y,i]and fj[gong[dot[s].x,dot[s].y],i] then
begin
map[dot[s].x,dot[s].y]:=i;
fh[dot[s].x,i]:=false;
fl[dot[s].y,i]:=false;
fj[gong[dot[s].x,dot[s].y],i]:=false;
used[s]:=true;
if dg=kcz then cl
else dfs(zsfa);
used[s]:=false;
map[dot[s].x,dot[s].y]:=0;
fh[dot[s].x,i]:=true;
fl[dot[s].y,i]:=true;
fj[gong[dot[s].x,dot[s].y],i]:=true;
end;
end;
end;
end;
begin
assign(input,'shudu.in');
assign(output,'shudu.out');
reset(input);
rewrite(output);
max:=0;
kcz:=0;
hg:=0;
dg:=0;
fillchar(fh,sizeof(fh),true);
fillchar(fl,sizeof(fl),true);
fillchar(fj,sizeof(fj),true);
fillchar(used,sizeof(used),false);
for i:=1 to 9 do
for j:=1 to 9 do
begin
read(map[i,j]);
if map[i,j]<>0 then
begin
hg:=map[i,j]*qvan[i,j]+hg;
fh[i,map[i,j]]:=false;
fl[j,map[i,j]]:=false;
fj[gong[i,j],map[i,j]]:=false;
end
else
begin
inc(kcz);
dot[kcz].x:=i;
dot[kcz].y:=j;
end;
end;
dfs(0);
if max=0 then write(-1)
else write(max+hg);
close(input);
close(output);
end.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

相关推荐