目录
一,不规则数独
1,规则
没有分9个宫,而是用特定的线分成9个区,其他规则和标准数独一样。
2,对称性
在我做过的这些不规则数独里面,居然全部有着对称性!
有的是格子有对称性,有的是数字有对称性,还有的是格子和数字都有对称性。
对称性又分很多很多种。
含正方形的不规则数独

这5个不规则数独,正中间都是正方形,而且里面给出的数字都是对称分布的。
具体说来
图一的格子是中心对称的,数字几乎是中心对称的。
图二的格子和数字都是左右对称的
下面一行的三个图,格子和数字都是中心对称的

这个图有2个正方形,也是格子和数字都是中心对称的。

这个图有3个正方形,格子是关于主对角线对称的,而数字是关于2条对角线都对称的。
中心对称的不规则数独
不规则数独有很多很多都是格子成中心对称的,比如下面这个:

然而更可怕的是,有的数独在此基础上,数字的位置也有着规律。



这3个数独,数字也是成中心对称的

这2个数独还是挺像的,而且,数字的位置,都是关于2个对角线对称的。
关于2个对角线对称是中心对称里面的一种,比一般的中心对称更具有对称美。


这3个数独,数字都是90°旋转对称。
90°旋转对称是中心对称里面的一种,比一般的中心对称更具有对称美。

这3个数独,一看就是非常非常对称,上下对称,左右对称,对角线对称,90度旋转对称
其他对称不规则数独

格子是关于副对角线对称的,而数字是上下对称而且左右对称

格子是左右对称的

格子是左右对称的,而数字是关于副对角线对称的。

格子是关于副对角线对称的,而数字是左右对称的。
3,计算机求解
前面我给出了用于求解任何规则数独的代码,这里我将对代码进行修改,得到可以用于求解任何不规则数独的代码。
不规则数独和规则数独的区别,在于划分9个区的方式不同,规则数独是9个3*3的正方形区,而不规则数独的分区各种各样的。
只需要用1个数组par记录如何分区,即可求解不规则数独。
代码:
#include<iostream>
using namespace std;
int list[10][10];
int par[10][10]; //par[i][j]=n
int anti[10][10]; //anti[n][?]=i*10+j;
void init()
{
cout << "输入数字,没有数字的用0代替" << endl;
char c;
for (int i = 1; i < 10; i++)for (int j = 1; j < 10; j++)
{
cin >> c;
list[i][j] = c - '0';
}
cout << "输入每个格子属于哪一块(1-9)" << endl;
for (int i = 1; i < 10; i++)for (int j = 1; j < 10; j++)anti[i][j] = 0;
for (int i = 1; i < 10; i++)for (int j = 1; j < 10; j++)
{
cin >> c;
par[i][j] = c - '0';
for (int k = 1; k < 10; k++)if (anti[par[i][j]][k] == 0)
{
anti[par[i][j]][k] = i * 10 + j;
break;
}
}
}
bool ok(int i, int j, int k)
{
for (int jj = 1; jj < 10; jj++)if (list[i][jj] == k)return false;
for (int ii = 1; ii < 10; ii++)if (list[ii][j] == k)return false;
int p = par[i][j];
for (int ii = 1; ii < 10; ii++)
if (list[anti[p][ii] / 10][anti[p][ii] % 10] == k)return false;
return true;
}
bool trys(int i, int j)
{
if (j == 10)
{
i++;
j = 1;
}
if (i == 10)return true;
if (list[i][j])return trys(i, j + 1);
for (int k = 1; k < 10; k++)
{
if (ok(i, j, k))
{
list[i][j] = k;
if (trys(i, j + 1))return true;
}
}
list[i][j] = 0;
return false;
}
void out()
{
for (int i = 1; i < 10; i++)
{
for (int j = 1; j < 9; j++)cout << list[i][j] << " ";
cout << list[i][9] << endl;
}
}
int main()
{
init();
trys(1, 1);
out();
system("pause>nul");
return 0;
}
在ok函数中,由任何一个格子的坐标,需要直接得到其他所有格子的坐标,所以需要一个数组anti将par反过来记录。
其实不用这个数组也行,大不了在ok里面做一个搜索,搜索81个格子,根据par值判断是否在一个区。
这样做,代码稍微简单一点点,虽然复杂度是一样的,但是时间肯定慢一些。
上面的代码,对于任何不规则数独,应该都能在2秒之内输出答案。
用法示例:

对于这个数独,将空格全部补0:
030159080
209000603
007803400
900040005
706000108
300090006
002907500
501000802
070516020
然后,将9个区编号1-9:

然后同样的变成9*9的方阵:
122333444
122333444
122233444
125253666
115555566
111859596
777889996
777888996
777888996
将这2个9*9的方阵输入程序即可得到答案:

所以答案是:

二,变种数独
1,规则
变种数独是在规则数独的基础之上,加一点点特殊的规则。
这些规则,有的也可以加在不规则数独之上,不过比较少见。
因为多了一些约束,所以相对来说,一般来说给出的数字比较少。
变种数独里面,有很多都是规定一些大小为9的区域,这些区域里面都是1到9的数字。
2,对角线数独
在规则数独的基础上,还要满足2条对角线也是1到9
比如这个:

除了很对称之外,好像没什么特点。
但是,这个数独很特殊,要自己去解才能体会。
在解这个数独的时候,你会感觉,这个数独几乎有一套独特的推理规则,
规则数独常用的方法在这里很不好用。
规则数独,用行唯一性、列唯一性是最多的。
而这个数独,行唯一性、列唯一性用的很少,反而对角线用的很多很多!
然而,比对角线用的更多的,是一个奇特的规律,仅对本数独有效!
这个规律我不明说,在下面的答案我用图画出来

对角线的规则可以叠加在其他变种数独之上,比如窗口数独,
也可以叠加在不规则数独之上。
3个奇特的数独:

这3个数独,一看就都有着较强的对称性。
然而,不仅是对称性,任何2个数字之间的曼哈顿距离都是偶数!
也就是说,如果把数独按照如下方式染色的话

这3个数独的所有数字都会被黑格子盖住!
他们的解分别是:

第一个数独很难,第二个数独难度普通,第三个数独很简单。
他们给出的初始数字分别有24、28、24个,但是因为结构差异很大,所以难度差别大。
这3个数独,共性很明显,却又都有着很独特的结构,解法截然不同,
而且都和普通的规则数独解法不太像,这些,只有自己去解才能体会的到!
3,窗口数独
在规则数独的基础上,还要满足4个灰色的宫也是1到9

答案:

4,超级窗口数独
在规则数独的基础上,还有9个块也都是1到9

约束比较多,答案:

5,奇偶数独
变种数独里面,还有各种奇偶数独,就是标出特定的区域必须是奇数或者必须是偶数。
情人节趣味数独
情人节趣味数独这个是奇偶数独的一种。

这个趣味数独的规则和规则数独差不多,只是标出了16个格子必须是偶数。
求解的过程也很有趣:

本文探讨了不规则数独的对称特性,如中心对称、对角线对称等,并展示了各种变种数独如倍数数独、武士数独的规则及求解技巧。重点讲述了规则退化现象在解题过程中的应用。
最低0.47元/天 解锁文章
1049

被折叠的 条评论
为什么被折叠?



