数独
数独通法[可解决任何数独问题](仅供参考)
第一步:看横行(原则:这行已确定数大于等于四)
每一个空格写入可能的数字(根据横纵行已有的,但不看九宫)
第二步:看九宫
划去无机会的数字
第三步;重复1
第四步:重复2
此时,已基本每个空格都有数字了(一般数独已解),并且横纵行,九宫原则(明显原则)均已用尽.
隐含原则1:{若一个单元(横行\纵行\九宫)某组内未确定格数,与其内部元素数相同,则这几个元素必在这几格内}例:
某一横行内所填确定数字如下:
(1.2)(6)(2.3.4)(7)(5.3)(9)(2.4)(8)(1.4)
在第1.3.7.9格(4个)内含1.2.3.4四个元素
所以,这四个数只能在其中,所以第五格内3去掉
第五步:重复1.2,利用隐含原则1
第六步:检验全局,利用1_5
此时仅仅余下几个格了(难的数独已解),还有第二隐含原则:
(1.2)(6)(2.3.4)(7)(5.3,8)(9,1)(2.4)(8,9)(1.4)
这一行很复杂,隐含原则一也很难奏效
但可见,数5在这一行仅有一次机会,所以,第五格只能是它!
第七步:重复1.2,利用隐含原则2
第八步:检验全局,利用1_7
所有数独已解,若解不出来,三种原因
1你解错了 2有一个条件没看见 3这个数独有问题
完毕!
数独技巧
数独技巧
格,那么就只能出现在这个宫格了.对于唯一候选数出现行,九宫格的情况,处理方法完全相同。
数独技巧
这是制作好的一张候选数表,注意观察B5,B9,D1。
可以看出在第1列,数字9只在D1出现。在第5列,数字3只在B5出现。在B9所处的九宫格里,数字9只有在B9出现。所以"9"是第1列的隐形唯一候选数,"3"是第5列的隐形唯一候选数,"9"是A7九宫格的隐形唯一候选数。[1]
编辑本段三链数删减法
找出某一列、某一行或某一个九宫格中的某三个宫格候选数中,相异的数字不超过3个的情形,进而将这3个数字自其它宫格的候选数中删减掉的方法就叫做三链数删减法。隐性三链数删减法:在某行,存在三个数字出现在相同的宫格内,在本行的其它宫格均不包含这三个数字,我们称这个数对是隐形三链数.那么这三个宫格的候选数中的其它数字都可以排除.
当隐形三链数出现在列,九宫格,处理方法是完全相同的.矩形顶点删减法,矩形顶点删减法和直观法讲到的矩形摒除法分析方法是一样的。矩形顶点删减法在识别时比较不容易找到,所以最好先使用其它的方法。三链数删减法的原理如下面图示:
在H行,H2,H5,H7的候选数(12),(23),(13),构成三链数,那么123这三个数在H行将只能出现在H2,H5,H7,那么本行其它宫格就可以删除这3个候选数了。这是三链数发生在行的情况。
在G7所在九宫格,G7,H8,I9的候选数(12),(23),(13),构成三链数,那么123这三个数在这个九宫格将只能出现在G7,H8,I9,那么本九宫格其它宫格就可以删除这3个候选数了。这是三链数发生在九宫格的情况。
三链数是数对的扩展,我们在对上面的三链数进行扩展,得到右边的特殊的三链数,只要保证在3个宫格内,其包含的候选数也为3个,就都
符合我们的要求,比如(123,123,123),(12,123,123)或(12,23,123)都符合要求。
我们进一步再扩充,发现只要在N个宫格内,其包含的候选数也恰为N 个,那么处理和三链数是相同的道理,这样就形成了四链数,比如
(12,23,34,14),(123,123,14,1234)等。甚至可以扩充到五链数,七链数(虽然在实际解题中作用不大了)。平时我们用到最多的就是三链数,四链数了。
在A4所在九宫格,我们看到B4~B6,形成三链数,则本九宫格其它宫格就可以去除候选数"2","7","9",这样就得到C6=4。
同上面完全相同的一副图,在A行,A7~A9形成由179构成的三链数,排除本行其它宫格的候选数179后得到A3=3。
编辑本段三链列删减法
三链列删减法是矩形顶点删减法的扩展,如果不清楚矩形顶点删减法,可以参考矩形顶点删减法,以便于更容易理解本节内容。利用“找出某个数字在某三列仅出现在相同三行的情形,进而将该数字自这三行其他宫格候选数中删减掉”;或“找出某个数字在某三行仅出现在相同三列的情形,进而将该数字自这三列其他宫格候选数中删减掉”的方法就叫做三链列删减法。关键数删减法在进入到解题后期,利用前面讲到的唯一候选数法、隐性唯一候选数法、区块删减法、数对删减法、隐性数对删减法、三链数删减法、隐性三链数删减法、矩形顶点删减法、三链列删减法都无法有进展的时候,可以考虑使用关键数删减法。关键数删减法就是在后期找到一个数,这个数在行(或列,九宫格)仅出现两次的数字。我们假定这个数在其中一个宫格类,继续求解,如果发生错误,则确定我们的假设错误。如果继续求解仍然出现困难,不妨假设这个数在另外一个宫格,看能不能得到错误。这就是关键数删减法。
如果数字“1”可能出现在B行、E行、G行的黄色宫格,则符合“某个数字在某三列仅出现在相同三行的情形”,符合三链列删减法的要求。
则红色宫格均不包含候选数“1”。
这时上图的一个变形。其中一行的“1”只能放在这一行的两个位置。处理和上图一样,红色宫格均可以排除候选数“1”。
数字"6"在第2列,第6列,第8列。均出现在A,B,I行。其中在第6列仅出现B,I行,仍然符合三链列删减法的要求。
编辑本段直观法解题技巧
数独直观法解题技巧主要有
单元限定法、单元排除法、区块排除法、唯一余解法、矩形排除法、逐行逐列依次扫描法、综合扫描法、唯一候选数法、隐性唯一候选数法、区
块删减法、数对删减法、隐性数对删减法、三链数删减法、隐性三链数删
减法、矩形顶点删减法、三链列删减法、关键数删减法、关连数删减法。
1.联除法。
在并排的三个九宫格中的两排寻找相同数字,再利用九宫格得出另一
排中该数字位置,该方法适用于中高级数独.
2.巡格法
找出在每个九宫格中出现频率较高的数字,得出该数字在其余九宫格
内位置,该方法应用于方法一之后。
3.排除法
这个方法是解决问题的关键,易被常人所忽略。在各行列或九宫格中
观察,若有个位置其它数字都不能填,就填余下的数字
4.待定法
此方法不常用却很有效。暂时确定某个数字在某个区域,再利用其来进行排除
5.行列法
此方法用于收官阶段,利用先从行列突破来提高解题效率。
6.假设法
作为一名高手,我不提倡这种方法。即在某个位置随机的填上一个数字,再进行推演,并有可能最终产生矛盾而否定结论.
7.频率法
这种方法相比于上一种方法更能提高效率。在某一行列或九宫格列举
出所有情况,再选择某位置中出现频率高的数字
8.候选数法
使用候选数法解数独题目需先建立候选数列表,根据各种条件,逐步
安全的清除每个宫格候选数的不可能取值的候选数,从而达到解题的目的。
使用候选数法一般能解比较复杂的数独题目,但是候选数法的使用没
有直观法那么直接,需要先建立一个候选数列表的准备过程,所以实际使
用时可以先利用直观法进行解题,到无法用直观法解题时再使用候选数法
解题。
候选数法解题的过程就是逐渐排除不合适的候选数的过程,所以在进
行候选数删除的时候一定要小心,确定安全地删除不合适的候选数,否则,很多时候只有重新做题了。有了计算机软件的帮助,使得候选数表的维护
变得轻松起来。
#include
#include
#include
char sd[81];
bool isok = false;
//显示数独
void show()
{
if (isok) puts("求解完成");
else puts("初始化完成");
for (int i = 0; i < 81; i++)
{
putchar(sd[i] + '0');
if ((i + 1) % 9 == 0) putchar('\n');
}
putchar('\n');
}
//读取数独
bool Init()
{
FILE *fp = fopen("in.txt", "rb");
if (fp == NULL) return false;
fread(sd, 81, 1, fp);
fclose(fp);
for (int i = 0; i < 81; i++)
{
if (sd[i] >= '1' && sd[i] <= '9') sd[i] -= '0'; else sd[i] = 0;
}
show();
return true;
}
//递归解决数独
void force(int k)
{
if (isok) return;
if (!sd[k])
{
for (int m = 1; m <= 9; m++)
{
bool mm = true;
for (int n = 0; n < 9; n++)
{
if ((m == sd[k/27*27+(k%9/3)*3+n+n/3*6]) || (m == sd[9*n+k%9]) || (m == sd[k/9*9+n]))
{
mm = false;
break;
}
}
if (mm)
{
sd[k] = m;
if (k == 80)
{
isok = true;
show();
return;
}
force(k + 1);
}
}
sd[k] = 0;
}
else
{
if (k == 80)
{
isok = true;
show();
return;
}
force(k + 1);
}
}
int main()
{
system("CLS");
if (Init())
{
double start = clock();
force(0);
printf("耗时%.0fms", clock() - start); }
else puts("初始化错误");
getchar();
}