目录

问题描述

问题分析

放码过来:


问题描述

如【图1.png】,玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一

行、每一列、每一个同色九宫内的数字均含1-9,不重复。

数独的答案都是唯一的,所以,多个解也称为无解。
本图的数字据说是芬兰数学家花了3个月的时间设计出来的较难的题目。但对会使用计算机编程的你来说,恐怕易如反掌了。
本题的要求就是输入数独题目,程序输出数独的唯一解。我们保证所有已知数据的格式都是合法的,并且题目有唯一的解。
格式要求,输入9行,每行9个数字,0代表未知,其它数字为已知。
输出9行,每行9个数字表示数独的解。

例如:
输入(即图中题目):

005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700

程序应该输出:

145327698
839654127
672918543
496185372
218473956
753296481
367542819
984761235
521839764

再例如,输入:

800000000
003600000
070090200
050007000
000045700
000100030
001000068
008500010
090000400

程序应该输出:

812753649
943682175
675491283
154237896
369845721
287169534
521974368
438526917
796318452

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。

问题分析

至于数独的要求,大家想必都很熟悉了,每行,每列以及每一个 3×3 的小方格都不能有相同的数字出现。那么,现在我们直接套回溯框架即可求解。

前文 回溯算法详解,已经写过了回溯算法的套路框架,如果还没看过那篇文章的,建议先看看

我们求解数独的思路很简单粗暴,就是对每一个格子所有可能的数字进行穷举。对于每个位置,应该如何穷举,有几个选择呢?

很简单啊,从 1 到 9 就是选择,全部试一遍不就行了

for (int k = 1; k < 10; k++){if (check(ss, x, y, k)){ss[x][y] = (char)('0' + k);dfs(ss, x + (y + 1) / 9, (y + 1) % 9);//处理下一个状态//回溯在这里也可以}}ss[x][y] = '0';//回溯}

emmm,再继续细化,并不是 1 到 9 都可以取到的,有的数字不是不满足数独的合法条件吗?

bool check(string* ss, int i, int j, int k)
{//检查同行和同列for (int l = 0; l < 9; l++){if (ss[i][l] == (char)('0' + k))return false;if (ss[l][j] == (char)('0' + k))return false;}//处理小九宫格for (int l = (i / 3) * 3; l < (i / 3 + 1) * 3; l++){for (int m = (j / 3) * 3; m < (j / 3 + 1) * 3; m++){if (ss[l][m] == (char)('0' + k))return false;}}return true;
}

而且现在只是给 j 加一,那如果 j 加到最后一列了,怎么办?

很简单,当 j 到达超过每一行的最后一个索引时,转为增加 i 开始穷举下一行,并且在穷举之前添加一个判断,跳过不满足条件的数字:(这里运用了小小的技巧)

 dfs(ss, x + (y + 1) / 9, (y + 1) % 9);//处理下一个状态

emmm,现在基本上差不多了,还剩最后一个问题:这个算法没有 base case,永远不会停止递归。这个好办,什么时候结束递归?显然 等于最后一行 的时候就说明穷举完了最后一行,完成了所有的穷举,就是 base case

if (x == 9){print(ss);exit(0);}

放码过来:

#include<iostream>
using namespace std;
void print(string* ss)
{for (int i = 0; i < 9; i++){cout << ss[i] << endl;}
}
bool check(string* ss, int i, int j, int k)
{//检查同行和同列for (int l = 0; l < 9; l++){if (ss[i][l] == (char)('0' + k))return false;if (ss[l][j] == (char)('0' + k))return false;}//处理小九宫格for (int l = (i / 3) * 3; l < (i / 3 + 1) * 3; l++){for (int m = (j / 3) * 3; m < (j / 3 + 1) * 3; m++){if (ss[l][m] == (char)('0' + k))return false;}}return true;
}
void dfs(string* ss, int x, int y)
{if (x == 9){print(ss);exit(0);}if (ss[x][y] == '0')//虚以待位{for (int k = 1; k < 10; k++){if (check(ss, x, y, k)){ss[x][y] = (char)('0' + k);dfs(ss, x + (y + 1) / 9, (y + 1) % 9);//处理下一个状态//回溯在这里也可以}}ss[x][y] = '0';//回溯}else {dfs(ss, x + (y + 1) / 9, (y + 1) % 9);//处理下一个状态}
}int main()
{string* ss = new string[9];for (int i = 0; i < 9; i++){cin >> ss[i];}dfs(ss, 0, 0);return 0;
}

好啦,今天就到这里,学累了吧xdm,上图缓解视觉疲劳

<<算法很美>>——(七)——DFS典题(二):数独游戏相关推荐

  1. 蓝桥杯算法很美笔记—排序实现题

    题1:小白上楼梯(递归设计) 小白正在上楼梯,楼梯有n阶台阶,小白一次可以上1阶,2阶或者3阶,实现一个方法,计算小白有多少种走完楼梯的方式. 思路: 一次可以上1阶,2阶或者3阶,则最后一步可以为上 ...

  2. <<算法很美>>——(七)——DFS典题(一):水洼数目

    目录 问题描述 问题分析 放码过来 问题描述 有一个大小为N×MN×M N\times MN×M的园子,雨后积起了水.八连通的积水被认为是连接在一起的.请求出园子里总共有多少水洼?八连通指的是下图中相 ...

  3. 算法很美——数学问题

    算法很美--数学问题 题1:天平称重 问题描述: 用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量. 砝码重量分别是1,3,9,27,81--3的指数次幂,每种重量砝码只有一个 则它们可以 ...

  4. 算法很美-位运算-找出落单的那个数

    上级目录:算法很美 1. 题目 一个数组里除了某一个数字之外,其他的数字都出现了两次.请写程序找出这个只出现一次的数字. 2. 异或思路 异或的运算是A ^ A=0,也就是说偶数个相同的元素异或,结果 ...

  5. 【算法很美】深入递归 (下)深度优先搜索DFS问题

    深搜.回溯.剪枝 深度优先搜索DFS 2.1 无死角搜索I 数独游戏 部分和 水洼数目 2.2 回溯和剪枝 n皇后问题 素数环 困难的串 小结 一些使用 2.1 无死角搜索I 数独游戏 你一定听说过& ...

  6. ybtoj DFS 1 拔河比赛 数独游戏 虫食算

    前情详见 dfs+search T1:拔河比赛 拔河比赛两边人数最多不能相差1 . 每个队员都有体重,我们要使两边比赛的人体重和相差最小. 现在有 n 个队员,韩老师想你帮忙分配,并且把分配后两边体重 ...

  7. 算法很美:水洼数(dfs)深搜

    题目描述 Descriptions: 由于近日阴雨连天,约翰的农场中中积水汇聚成一个个不同的池塘,农场可以用 N x M (1 <= N <= 100; 1 <= M <= 1 ...

  8. 最全的2021蓝桥杯算法课《算法很美》的学习笔记总目录+真题详解

    这里写目录标题 第一章 位运算 第二章 递归 第三章查找与排序

  9. <<算法很美>>——(三)十大排序算法(上)

    目录 前言 冒泡排序 图解冒泡 代码实现 冒泡优化 选择排序 图解选排​ 代码实现 插入排序 图解插入 ​代码实现 希尔排序 图解希尔 ​代码实现: 归并排序 图解归并 ​代码实现 快速排序 图解快排 ...

最新文章

  1. zabbix 3.2.2 server端(源码包)安装部署 (一)【转】
  2. “物联网”架构有多重要?
  3. 对高并发流量控制的一点思考 推荐
  4. 图片去字工具_这些免费工具轻松提取图片中的文字,别再傻傻地手工去输了
  5. 04.openssl编程——哈希表
  6. java按键发出声音代码_怎么在java中给按钮添加声音?
  7. 大数据技术之 Kafka (第 2 章 Kafka快速入门)
  8. 多柱汉诺塔最优算法设计探究
  9. 【论文】基于特定实体的文本情感分类总结(PART III)
  10. “WiFi 万能钥匙”盗 9 亿用户数据,如何看待运营平台滥用隐私的问题?
  11. 2020-05-05
  12. Typora修改空格样式(blockquote)
  13. ubuntu 18.04 安装搜狗拼音输入法(没有坑)
  14. 如何解决High Sierra 10.13.6 系统iCloud无法连接的问题?
  15. Fewest Flops
  16. [转] ReactNative Animated动画详解
  17. iOS14适配【解决iOS14下pop多层控制器至首页时,tabbar不显示问题】之问题分析篇
  18. 亚马逊运营关于卖家收到侵权邮件怎么办?
  19. 计算机组成原理之基本组成
  20. 杂谈:用 Sublime Text 2 写 ActionScript3

热门文章

  1. 基于OpenCV的摄像头人脸检测
  2. 提交代码时用prettier自动格式化
  3. Win10、Win11打开远程桌面连接方法
  4. 电机集电环是如何更换与运行的
  5. BIM算量与传统算量软件的对比和模型精准解决方案
  6. Markdown格式表情包大全最新整理分享
  7. Hadoop-提高性能(调优)方法
  8. 码绘VS手绘(二)动态绘图
  9. Use HAProxy to load balance 300k concurrent tcp socket connections: Port Exhaustion, Keep-alive and
  10. 2022.04.17-高宝琪毕设阶段性汇报