深搜解数独的c++程序


深搜解数独的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")

总结

小白到此水一篇,今天的事拖明天。
干饭能炫三斤肉,熬夜砸键赛神仙。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值