文章目录
深搜解数独的c++程序
终于办完了离职,在某辅导机构的底层打工人领着最低的工资干最多的活挨最狠的骂,现在要找下一份工作了,搞搞开发嘛,于是继续练习一些代码的编写。今天花了好久才设计好这个递归版的深搜,没办法,基础太差。说实话,之前只练过几个深搜的程序,也没学过,都是营地里看学生代码悟的,他们的代码那叫一个难读,变量都是abcd,好吧,我写的也是这样。总而言之言而总之,下面是代码直接奉上,注释我已经努力在写了,也恳请各位大佬的批评指正(如果有人看的话),我可太想上进了(挺起骄傲的小胸脯)。
代码
#include <iostream>
using namespace std;
//解数独的程序,输入9*9的方阵,均为0-9之间的数,0表示空格,程序会用其他数字取代0并输出数独的解方阵,无解也输出无解
//但是有一个bug,如果题目原本填入的数字中就有一些是有逻辑错误的组合,程序并没有做检验。
int a[15][15] = {}, dxy[10] = { 0, 0, 1, 2, 9, 10, 11, 18, 19, 20 };
bool dfs(int x, int y) {
//如果已经走到最后一格而且最后一格本来就有数字,则反馈解完了。
if (x == 9 && y == 9 && a[x][y] != 0) {
return true;
}
//如果当前的格子不等于零,说明要继续向后探索,此时直接反馈后续探索的结果即可
if (a[x][y] != 0) {
return dfs(x + y / 9, y % 9 + 1);
}
//使用vis数组用来存储当前的空格不可以填入的数字,可以填入的数字不会被做标记
int vis[10] = {};
//下面的循环中将当前的格子有关系的所有格子都遍历了一遍,将不可以填入的数字在vis里标记为1
for (int i = 1; i <= 9; i++) {
vis[a[i][y]] = 1;
vis[a[x][i]] = 1;
//下面的算式是通过dxy偏移量数组来遍历九宫格内的九个格点
int now = ((x - 1) * 9 + y - 1) / 27 * 27 + ((x - 1) * 9 + y - 1) % 9 / 3 * 3;
vis[a[(now + dxy[i]) / 9 + 1][(now + dxy[i]) % 9 + 1]] = 1;
}
//遍历在vis里没有做标记的数字,尝试填入这个数字
for (int i = 1; i <= 9; i++) {
if (vis[i] == 0) {
//在当前的格子里填入能够填入的数字
a[x][y] = i;
//如果填入后填满了就反馈解完了
if (x == 9 && y == 9)return true;
//如果没有解完,那么先继续填后面的看反馈的结果,如果反馈不能解完则回溯,否则向上一层反馈解完了。
if (!dfs(x + y / 9, y % 9 + 1)) {
a[x][y] = 0;
}
else {
return true;
}
}
}
//循环执行完而且没有做反馈说明无数可填了,就反馈解不了,要么回溯,要么上面的各层仍然回溯不了得到无解的情况
return false;
}
int main() {
//输入
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
cin >> a[i][j];
}
}
//换行方便后续输出
cout << endl;
//调用深搜函数
if (!dfs(1, 1)) {
cout << "无解";
return 0;
}
//循环输出二维数组
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
cout << a[i][j] << ' ';
}
cout << endl;
}
}
// 64 位输出请用 printf("%lld")
总结
小白到此水一篇,今天的事拖明天。
干饭能炫三斤肉,熬夜砸键赛神仙。