什么是数独

数独(shù dú)是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。已知有9行9列的格子,且被分成9个3*3的方块。其中一些格子内有数字,数值的范围为1-9 。玩家需要在其余的空白格子上填入数字,数字的范围也是1-9,要求所有空格都被填满而且满足以下条件:

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
    例如:
    一个数独题目如下:

    一种解法如下:

    红色数字为玩家填入的答案,满足每一行、每一列、每一个3*3黑边方块内所有的数字不重复。

解题方法

大体方向

找出当前的各种解法,不断地填入可能的数字,如果证实解法错误则撤回,继续尝试其他解法。
使用递归的方法,尝试各个可能的解,并且向上一层返回尝试的结果(成功或者失败)。
递归函数的处理过程如下:

  1. 如果数独已经完成,则大功告成。向上一层返回成功的信息。
  2. 推测出每一空白格的可能填入的数字。
  3. 找到可选数字最少的那一格。
  4. 如果有可选的数字,到步骤 5,否则返回失败的信息 。
  5. 填入一个可能的数字,生成新的数独。
  6. 调用递归函数处理新的数独,跳到下一层步骤 1。
  7. 得到下一层的返回信息,如果是失败跳到步骤 8,否则返回成功的信息。
  8. 如果还有下一个可选的数字,跳到步骤 5,否则返回失败的信息。

相关技巧

  • 利用ASCII编码 和 减法 来把字符转数字,如 ‘1’ - ‘0’ 得到数值 1 。
  • 使用位来记录数字1-9,可以用 unsigned int 类型从右往左数的第k位代表数字k。
  • 使用数字 1 左移来定位相应的位,如 1 << k 代表右往左数的第 k+1 位。
  • 使用 或运算 和 与运算 来操作相关的位。
  • 对于 i 行 j 列的小方格,使用 i / 3 * 3 + j / 3 即可以得出相应3 * 3方块的下标。
  • 使用__builtin_ctz() 函数可以迅速得出变量二进制表示时,末尾0的数量。
  • 使用__builtin_popcount() 函数可以迅速得出变量二进制表示时1的数量。

代码分享

class Solution {public:void solveSudoku(vector<vector<char>>& board) {unsigned int pos_r[9];//每一行剩下的可选数字unsigned int pos_l[9];//每一列剩下的可选数字unsigned int pos_b[9];//每一方块剩下的可选数字//一开始九个数字都是可选的,9个位全部为1for (int i = 0; i < 9; i++){pos_r[i] = 0b111111111;pos_l[i] = 0b111111111;pos_b[i] = 0b111111111;}for (int i = 0; i < 9; i++){for (int j = 0; j < 9; j++){if(board[i][j] != '.' ){//出现了新的数字,空白格用点号表示unsigned int bit = 1 << (board[i][j] - '1');pos_r[i] &= ~bit;//把相应的位置为0pos_l[j] &= ~bit;pos_b[i/3*3+j/3] &= ~bit;}}}slove(board, pos_r, pos_l, pos_b);//调用函数}bool slove(vector<vector<char>>& board, unsigned int *pos_r, unsigned int *pos_l, unsigned int *pos_b){int min_choice = 10;int a = 0, b = 0;unsigned int pos_bit = 0;for (int i = 0; i < 9; i++){for (int j = 0; j < 9; j++){if(board[i][j] == '.' ){//该位置没有填unsigned int possible = pos_r[i] & pos_l[j] & pos_b[i/3*3+j/3];//计算出同时满足三个条件的数字if (possible == 0) return false;//无解int choice = __builtin_popcount(possible);//计算可能的数字有多少(1的位数)if (choice < min_choice){//找到可填入数字最少的min_choice = choice;a = i;b = j;pos_bit = possible;}}}}if (min_choice == 10) return true; //全部填完了,返回//pos_bit 记录可能的数字while(pos_bit){unsigned int test_bit = 1 << __builtin_ctz(pos_bit);//从最右边的位开始(选最小的数字)board[a][b] = __builtin_ctz(pos_bit) + '1';//填入数字pos_r[a] &= ~test_bit;pos_l[b] &= ~test_bit;pos_b[a/3*3+b/3] &= ~test_bit;if (slove(board, pos_r, pos_l, pos_b)){return true;//成功 返回}//失败,撤回后继续试board[a][b] = '.';pos_r[a] |= test_bit;pos_l[b] |= test_bit;pos_b[a/3*3+b/3] |= test_bit;//清除试过的位pos_bit &= ~test_bit;}return false;//找不到解}
};

解9*9数独算法(C++)相关推荐

  1. 花了1晚上diy的matlab解数独算法,很好理解!

    花了1晚上diy的matlab解数独算法,很好理解! 前言 一.数独的规则 二.算法 1.思路 2.流程图 3.Matlab代码 总结 前言 老婆最近迷上了数独,还给我拍了张照片,初步了解了规则之后, ...

  2. 数独算法-递归与回溯

    1.概述 数独(Sudoku)是一种运用纸.笔进行演算的逻辑游戏.玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个粗线宫内的数字均含1-9,不重复. 1)终盘 ...

  3. python回溯法解9*9数独

    文章目录 前言 一.回溯法解数独代码 总结 前言 看了labuladong算法小抄里的回溯法,照着模板,加入自己的理解,用python做了个解9*9数独的回溯法,. 一.回溯法解数独代码 直接上代码: ...

  4. java课程 数独 文库_通俗易懂的数独算法(java版)

    数独算法 一 知识背景 无 二 绪言 偶尔玩下休闲益智小游戏,一方面可以舒解下心情,另一方面刺激下大脑皮层.百度了一下数独的起源和概念.说了那么多,看着就累.精简一下就是数字(0-9)填充游戏.不明白 ...

  5. “论解不了数独所以选择做个数独游戏这件事”

    有一天,小明同学在津津有味的逛力扣网站的时候,惊喜的发现了一个看似非常好下手的题目(万恶之源 T T). 于是小明同学又津津有味的写了解题思路. 像往常一样打开了Unity准备开始做. .(画UI) ...

  6. C++ sodoku solve数独算法(附完整源码)

    sodoku solve数独算法 sodoku solve数独算法的完整源码(定义,实现,main函数测试) sodoku solve数独算法的完整源码(定义,实现,main函数测试) #includ ...

  7. 完成数独的算法 python_python实现数独算法实例

    本文实例讲述了python实现数独算法的方法.分享给大家供大家参考.具体如下: # -*- coding: utf-8 -*- ''' Created on 2012-10-5 @author: Ad ...

  8. 用python设计数独的心得体会_python实现数独算法实例

    本文实例讲述了python实现数独算法的方法.分享给大家供大家参考.具体如下: # -*- coding: utf-8 -*- ''' Created on 2012-10-5 @author: Ad ...

  9. python:实现9×9二维数组数独算法(附完整源码)

    python:实现9×9二维数组数独算法 from __future__ import annotationsMatrix = list[list[int]]# assigning initial v ...

最新文章

  1. python小游戏系列记忆宫殿,儿时的回忆
  2. Python IDLE启动报错
  3. Shiro之从数据库初始化角色权限信息
  4. spark1.0和2.0的区别_【系统】华为正式发布鸿蒙OS 2.0手机Beta版:UI界面、交互无区别...
  5. 分析java 线程占用内存_Java线程:保留的内存分析
  6. java学习(82):静态代码块内部类
  7. VS2010 C++编译报错LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  8. Git 的安装及配置
  9. html转义 在线,HTML转义工具 [Javascript版]
  10. MSDN官方数据库开发群
  11. 智能优化算法论文python复现,附代码--鲸鱼优化算法(WOA)-1
  12. WAP1.X/WAP2.0以及WAP浏览器的协议版本
  13. 解决 Android App 上架 Google play后 ,签名变更,第三方sdk无法登录
  14. 【转】智能家居 系统安装及HA系统介绍
  15. GPU 编程与CG 语言之阳春白雪下里巴人——CG学习读书笔记之数学函数(三)
  16. scanf ---------未完待续
  17. 计算机专业学习规划,计算机专业学习计划.doc
  18. 文本表示(一)—— word2vec(skip-gram CBOW) glove, transformer, BERT
  19. VS Code中使用PlantUML绘图
  20. AForge学习笔记(5):AForge.Imaging(下)

热门文章

  1. 启动kafka2.8报afka.common.KafkaException: No `meta.properties` found in /tmp/kraft-combined-logs
  2. NC-Verilog仿真
  3. PRD(Product Requirement Document,产品需求文档)模板
  4. scala面向对象基础---类继承和特质
  5. 基于C++的简易RLC电路仿真器与滤波器仿真测试
  6. qt中在QLabel上显示图像并画矩形框。
  7. 《MySQL必知必会》第8篇:存储过程、函数
  8. SPSS显著性差异分析及字母标记
  9. iMX6UL配置MCP2515模块(SPI转CAN)——基于迅为iTOP-iMX6UL开发板
  10. 自然生长不含咖啡碱的茶树新品种--T三有机可可茶