DFS算法解决数独问题

一,情景描述

  一天晚自习,看到女朋友在旁边玩数独,便想着不如用个算法帮助她快速通关。毕竟,我想以后能成为一个AI算法工程师,所以现在不管是什么算法,多写点总归是有好处的。
  对于这个程序的功能,我希望它能够从文件夹里读取棋盘,然后运行之后输出完整的棋盘。这样对于不同的棋盘,只要更改一下文件路径,就能输出结果。其实,我想着利用计算机视觉就可以直接输入图片,然后电脑自己处理自己输出。但是奈何大二的自己还对计算机视觉一无所知,就只能手动输入到文本文件中了。

二,最初思路

  最开始,我的思路是1,先将棋盘遍历一遍,获取所有空格位置(横纵坐标),然后将他们放在一个数组里面。2,由于每个空格位置所填的内容是1~9之间的数字,所以对每个空格,从1开始,按照行列和所属九宫格进行三次筛选,删去不可能的数值。3,经过前两步的筛选,就可以锁定每个空格能够填的几个数字。然后利用蛮力法进行一种一种的尝试。
  为了实现这个思路,首先定义数据结构如下:

struct point{int x,y;  //表示棋盘的每一格所在行,所在列strign maynum="123456789";   //初始设置空格可能所取的值int index;   //用来指示具体空格的值
}

如上,设置了这样一个复杂的结构,并定义了一个一维数组 point zero[n];
zero[m] 表示第m+1个空格。则zero[m].x和zero[m].y就能分别表示这个空格在棋盘的第几行第几列,zero[m].string[zero[m].index]; 就能表示这个空格的值。于是,照着这个思路,我完成了最初思路的前面两步,等到最后一步准备蛮力法的时候,发现不知道该如何遍历了。要是硬生生继续写下去,那怕不是要写出个m层循环出来,瞬间失去方向。最终,我还是选择来到CSDN上观摩各位大佬的文章。才学得了DFS算法的思路(上学期学习数据结构,学到图的遍历时,怎么没想到这DFS如今还能派上用场。)

三,最终思路

  最终思路为:先从第一个空格开始,对其调用dfs算法为其赋上一个可能值,如果合法,则对下一个空格调用dfs算法。如果有一个空格所有可能值都不合法,则跳出递归函数返回上一个空格,对其赋值下一个可能值,再重复往后进行,知道能够输出全部完整的棋盘为止。完整代码如下:

#include<iostream>
#include<string>
#include<fstream>using namespace std;
int dataa[10][10];//建立二维数组用来存储数独棋盘
void Create()
{ifstream infile;infile.open("D:\\Visual Studio 2017\\代码项目文件夹\\Project1\\数独3.txt", ios::in);if (!infile.is_open()){cout << "读取文件失败" << endl;exit(-1);}char n[100];    //辅助数组,用于读取文件中的数据 然后转移到二维数组中int f = 0;while (!infile.eof())    //逐字符读取infile >> n[f++];f = 0;for (int i = 0; i < 9; i++)for (int j = 0; j < 9; j++)dataa[i + 1][j + 1] = n[f++] - '0';infile.close();
}int judge(int x, int y, int z)//判断是否有重复的z
{for (int j = 1; j < 10; j++) {//横行if (dataa[x][j] == z)return 0;}for (int j = 1; j < 10; j++) {//纵行if (dataa[j][y] == z)return 0;}int tempx = (x - 1) / 3, tempy = (y - 1) / 3;for (int j = 1; j <= 3; j++) {//3*3for (int k = 1; k <= 3; k++)if (dataa[tempx * 3 + j][tempy * 3 + k] == z)return 0;}return 1;
}
void print()
{for (int i = 1; i < 10; i++) {cout << " | ";for (int j = 1; j < 10; j++){cout << dataa[i][j];if (j % 3 == 0)    // 1 2 3   4 5 6   7 8 9{cout << " | ";}}if (i % 3 == 0){cout << endl;cout << " -------------------";}cout << endl;}
}
void dfs(int x, int y) {if (x > 9) {//结束print();cout << endl;return;}if (dataa[x][y] == 0)    //检测到这是一个空格{for (int i = 1; i < 10; i++)  //可能值从1开始,一直到9{if (judge(x, y, i))     //如果这个可能值合法{dataa[x][y] = i;dfs((x + (y + 1) / 10), (y + 1) > 9 ? 1 : (y + 1));   //向下一个空格递归,遍历}}dataa[x][y] = 0;     //如果这个空格的所有可能值填入都不合法,则将该空格清零,然后跳出递归函数,返回上一格}elsedfs((x + (y + 1) / 10), (y + 1) > 9 ? 1 : (y + 1));
}
int main()
{Create();dfs(1, 1);return 0;
}

算法总结

  不用设置那么麻烦的数据结构,直接利用dfs算法(前提是对该算法很熟悉并能灵活运用。)算法本身还要利用一个判断可能值是否合法的函数。Judeg函数中,对九宫格的判断不用分成九种情况讨论,要观察空格坐标的特点,直接分析出公式,可以提高时间复杂度,减少代码冗余度。
  同时对dfs进行递归调用时,dfs((x + (y + 1) / 10), (y + 1) > 9 ? 1 : (y + 1));这里的参数设置就很巧妙,利用求模,直接用一个式子就对二维数组进行了遍历,非常的方便。

写在最后

  虽然这次自己的思路没有成功,最后还是借鉴的大佬的算法,但是总归还是有收获的。作为这学期第一个自己主动尝试编写的课程之外的算法,我觉得还是一个挺好的开头的。转眼间,大二这学期已经开学整整四周了,可自己的状态好像还没有完全调整过来。这学期的专业课更难了,时间也更加紧张。面对眼前这条成长为一个优秀的AI算法工程师的道路,我也应该停止空想,真正开始往前大踏步前进。希望每一步都能踩出一个深深的印记!作为这学期在CSDN上的第一篇博客,它将开启全新的《算法设计与分析》这一专栏,希望能够记录下自己学习的点滴。

DFS算法解决数独问题相关推荐

  1. java回溯算法解决数独_js回溯算法解决数独问题

    直接上代码 代码里面注释很清晰 传说中的最难数组大概是在20ms左右解决 /** * 数独算法 */ class Sudoku { constructor({ display = false, sud ...

  2. dfs算法解决哈密顿图问题

    问题简介: 输入样例: 5 7 2 1 3 1 4 1 4 2 5 2 5 3 5 4 1 输出样例: Path 1: 1 2 4 5 3 1 Path 2: 1 3 5 2 4 1 Path 3: ...

  3. 数独小项目开篇:DFS解决数独难题

    数独小项目开篇:DFS解决数独难题 前言 DFS解决数独问题思路 代码实现细节 样例测试 总结 Reference 前言   这周小刀是挺忙的,周末加班,哎,谁不是996呢?(打工魂燃烧吧~   这次 ...

  4. POJ2676,HDU4069解决数独的两种实现:DFS、DLX

    搜索实现:解决数独有两种思考策略,一种是枚举当前格能填的数字的种数,这里有一优化策略就是先搜索能填入种数小的格子:另一种是考虑处理某一行(列.宫)时,对于某一个没用过的数字,若该行(列.宫)只有一个可 ...

  5. 深度搜索----深度搜索解决数独问题

    深度搜索----深度搜索解决数独问题 1.深度优先搜索(DFS) 从某个状态开始,不断的转移状态直到无法转移,然后回退到前一步的状态,继续转移到其他状态,如此不断重复,直到找到最终的解. 2.数独问题 ...

  6. LeetCode算法 —— 解数独

    题目如下所示: 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以粗实 ...

  7. 解决数独问题用人工智能还是量子计算?

    作为一种有趣的棋盘游戏,数独诞生100周年之后,它是如何成为计算研究的焦点之一的呢?探索如何使用人工智能或量子计算机从头开始创建一个智能数独求解器. 在深入探究之前,先来了解一下历史 马克•布洛赫说: ...

  8. quantum_用ai或Quantum解决数独

    quantum 人工智能 , 计算机科学 (Artificial Intelligence, Computer Science) 深入了解之前的一些历史记录: (A little bit of his ...

  9. NeurIPS 2018 | 如何用循环关系网络机智地解决数独类关系推理任务?

    选自 arXiv 作者:Rasmus Berg Palm.Ulrich Paquet.Ole Winther 机器之心编译 参与:李诗萌.王淑婷 本文引入循环关系网络来解决步骤相互依赖的关系推理任务, ...

最新文章

  1. 如何解决VS2015编译C4996错误
  2. 使用varnish + nginx + lua搭建网站的降级系统
  3. linux——管理系统存储之设备的识别、发现、挂载
  4. 泛华金控携手神策数据,赋能保险经代公司筑就全闭环智能营销
  5. Applese 的回文串
  6. 2021年 第12届 蓝桥杯【备赛直播公开课 —— 软件类(本科组、高职高专组)】
  7. Spring Cloud 5分钟搭建教程(附上一个分布式日志系统项目作为参考) - 推荐
  8. python方法大全参数是对象_向对象方法Python传递太多参数
  9. JVM内存分配策略原
  10. 光干涉波谷,有可能低于绝对零度
  11. php 漏洞扫描,10个最佳PHP代码安全扫描程序来查找漏洞
  12. 项目启动时就执行某些操作、@Scheduled定时项目启动时执行一次
  13. java kvm_KVM环境搭建
  14. 2021前端面试经常被问到的题(附答案)
  15. android adb pull 文件夹,android – 我如何adb拉SD文件夹中的所有文件
  16. 计算机网络实践网线制作,一种用于计算机网络对接网线接头的制作方法
  17. php 正文提取算法,基于机器学习的网页正文提取方法
  18. Win11如何清理C盘垃圾文件
  19. elementui表格如何自定义表头内容,让表头变得更美观
  20. 移动智能开发平台群雄逐鹿-塞班(Symbian),WinCE,黑莓(Blackberry),QT/Qtopia,iOS,Android

热门文章

  1. 排队问题解题思路_双点医院解决全科排队方法 双点医院怎么解决排队问题
  2. 微服务中鉴权方式OAtuh2与JWT的比较
  3. Netty In Action中文版 - 第十二章:SPDY
  4. Adroid项目源码,面试题
  5. i58250u是低端处理器吗_华为畅享20Plus处理器是什么?CPU性能打王者和吃鸡流畅吗...
  6. plt.colorbar颜色条
  7. Kafka Tool 2 使用教程 SASL_PLAINTEXT
  8. 系统动力学模型_不同包装系统下生牛肉中金黄色葡萄球菌的生长动力学预测模型...
  9. 【3D建模制作技巧分享】ZBrush如何重新拓扑
  10. iOS 流量监控分析