版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
这几天数据结构作业较多涉及回溯算法,课堂上老师讲到数独的可行解问题,虽然以前做过一点,但不是很了解数独,但是凭借目前掌握的回溯或者DFS还是可以解出一些答案的。
思路解答:
数独的规则无外乎就是同一行,同一列不能存在相同的数,这么说来,和八皇后问题感觉差不多了,利用这个规则限制,作为判断条件,然后当然是多次遍历,试错,计算解了。
代码实现:
#include<iostream>
using namespace std;
int t = 0,map[81][81];//设最大值,毕竟太多了,耗时间
int answer = 0,count = 0;//计数
void Output();
int CheckFunction(int, int);
void DFSFunction(int);
void OutputFunction();
int main()
{
cout<<"请输入数独矩阵规模:";
cin>>t;
cout << "请输入一个"<<t<<"*"<<t<<"的数独矩阵,空位以0表示:" << endl;
char temp[t][t],i,j;
for(i = 0;i <= t - 1;i++){//读入数据
for(j = 0;j <= t - 1;j++){
cin>>temp[i][j];
map[i][j] = temp[i][j] - '0';
}
}
DFSFunction(0);//深度搜索
if(count > 0)
cout<<"一共有"<<count<<"种解决方案"<<endl;
else
cout<<"无解"<<endl;
}
int CheckFunction(int n, int key)//判断合法性
{
int i,j;
for(i = 0;i <= t - 1;i++)//同行
if(map[n/t][i] == key)
return 0;
for(i = 0;i <= t - 1;i++)//同列
if(map[i][n%t] == key)
return 0;
int x = n / t / (t/3) * (t/3);
int y = n % t / (t/3) * (t/3);
for(i = x;i < x + t / 3;i++){//小三矩阵判断
for(j = y;j < y + t / 3;j++)
if(map[i][j] == key)//出现同值
return 0;
}
return 1;
}
void DFSFunction(int n)
{
if(n > t*t - 1){//结束即为全部遍历
answer = 1;
return ;
}
if( map[ n / t ][n % t] != 0 )//初始化已经给值
DFSFunction(n + 1);
else{
for(int i = 1;i <= t;i++){
if( CheckFunction(n,i) ){//检验合法性
map[n / t][n % t] = i;
DFSFunction(n + 1);//深度搜索
if(answer == 1){//有解
count++;
Output();
answer = 0;
}
map[n / t][n % t] = 0;//回溯
}
}
}
}
void Output()
{
cout<<count<<endl;
for(int i = 0;i <= t - 1;i++){//输出方案
for(int j = 0;j <= t - 1;j++)
cout<<map[i][j]<<" ";
cout<<endl;
}
cout<<" "<<endl;
}
结果:
我输入9个0后:
总的来说,矩阵规模越大,耗时肯定越多。但我了解到有一种数独分组轮转算法,听说效率更高,后续再更新。