一,数独的规则

  1. 横向上9个数字满足1-9不重复;
  2. 竖向上9个数字满足1-9不重复;
  3. 将大网格拆分为9个3*3的小网格,每个小网格内同样满足1-9不重复

二,生成数独的思路

首先准备一个空的数独,从第一个格子开始,按照数独的规则,把1-9依次试探性的填入,如果合法,就填入.如果不合法就判断下一个数合不合法,这样,一直到把第81个格子填完,就生成了一个完整的数独,但是因为这样生成的数独是一个固定的,所以,现在我们要随机把它打乱,根据数独的特性,在同一个小九宫格中的行和行之间交换位置,列与列之间交换位置,数独依然成立,打个比方,第0行和第2行,交换位置,第0列和第2列交换位置,数独依然成立.

  这样随机打乱位置后,再根据要求的难度,随机挖空其中的一些格子,这样就生成了我们需要的数独题目了!

bool isValid(int row, int col, int num, vector<vector<char>>&board){//检查行有没有重复的,如果有返回faulsefor (int i = 0; i < board.size(); i++){if (num == board[row][i]-'0'){return false;}}//检查列有没有重复的,如果有返回faulsefor (int i = 0; i < board.size(); i++){if (num == board[i][col]-'0')return false;}//检查数字所在的方块有没有重复的,如果有返回faulseint startrow = row / 3 * 3;int startcol = col / 3 * 3;int endrow = startrow + 3;int endcol = startcol + 3;for (int i = startrow; i < endrow; i++){for (int j = startcol; j < endcol; j++){if (num == board[i][j]-'0')return false;}}return true;}void swapCol(int m, int n, vector<vector<char>>& board){vector<char>temp(board.size(), ' ');for (int i = 0; i < board.size(); i++){temp[i] = board[i][m];board[i][m] = board[i][n];board[i][n] = temp[i];}}void selectBlank(int nums, vector<vector<char>>& board){srand(time(NULL));while (nums){int row = rand() % 9;int col = rand() % 9;if (board[row][col] != '.'){board[row][col] = '.';nums--;}}}void create(int blank, vector<vector<char>>& board){//小九宫格中的行和列交换,有以下9种交换方式int choice[9][2] = { {0,1},{0,2},{1,2},{3,4},{3,5},{4,5},{6,7},{6,8},{7,8} };srand(time(NULL));//设置动态种子for (int j = 0; j < 3; j++)//J代表交换次数,也可以不用这个循环,就交换一次{int i = rand() % 9;//取0-8之间的随机值board[choice[i][0]].swap(board[choice[i][1]]);//随机交换两行swapCol(choice[i][0], choice[i][1], board);//随机交换两列}selectBlank(blank, board);//根据难度可以选择不同数量的空格}

三,计算数独的思路

根据提供的数独,从第一个方格开始遍历,先判断是不是空,如果为空就把1-9依次试探性的填入,然后根据数独的规则,判断填入的数合不合法,如果合法就填入.然后递归遍历下一个方格,如果判断出下一个方格填入失败,说明现在填入的数是错的,需要回溯,然后把这个填入的数改为空,然后继续试探别的数字,如果所有数字试完都不行,那么就返回false,回溯到上一个数字.

这样直到把所有空格都遍历完成.

完整代码为:

// two.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime>
#include<Windows.h>
using namespace std;class sudoku
{
public:bool active = false;sudoku(vector<vector<char>>&board){// printBoard(board);active = dfs(board, 0);}void printBoard(vector<vector<char>>&board){cout << " |---|---|---|---|---|---|---|---|---| " << endl;for (int i = 0; i < board.size(); i++){for (int j = 0; j < board.size(); j++){cout << " | " << board[i][j];}cout << endl;cout << "  ---|---|---|---|---|---|---|---|---| " << endl;}}bool isValid(int row, int col, int num, vector<vector<char>>&board){//检查行有没有重复的,如果有返回faulsefor (int i = 0; i < board.size(); i++){if (num == board[row][i]-'0'){return false;}}//检查列有没有重复的,如果有返回faulsefor (int i = 0; i < board.size(); i++){if (num == board[i][col]-'0')return false;}//检查数字所在的方块有没有重复的,如果有返回faulseint startrow = row / 3 * 3;int startcol = col / 3 * 3;int endrow = startrow + 3;int endcol = startcol + 3;for (int i = startrow; i < endrow; i++){for (int j = startcol; j < endcol; j++){if (num == board[i][j]-'0')return false;}}return true;}void swapCol(int m, int n, vector<vector<char>>& board){vector<char>temp(board.size(), ' ');for (int i = 0; i < board.size(); i++){temp[i] = board[i][m];board[i][m] = board[i][n];board[i][n] = temp[i];}}void selectBlank(int nums, vector<vector<char>>& board){srand(time(NULL));while (nums){int row = rand() % 9;int col = rand() % 9;if (board[row][col] != '.'){board[row][col] = '.';nums--;}}}void create(int blank, vector<vector<char>>& board){//小九宫格中的行和列交换,有以下9种交换方式int choice[9][2] = { {0,1},{0,2},{1,2},{3,4},{3,5},{4,5},{6,7},{6,8},{7,8} };srand(time(NULL));//设置动态种子for (int j = 0; j < 3; j++)//J代表交换次数,也可以不用这个循环,就交换一次{int i = rand() % 9;//取0-8之间的随机值board[choice[i][0]].swap(board[choice[i][1]]);//随机交换两行swapCol(choice[i][0], choice[i][1], board);//随机交换两列}selectBlank(blank, board);//根据难度可以选择不同数量的空格}bool dfs(vector<vector<char>>&board, int start)//从0开始依次遍历81个格子,计算此数独{if (start == 81)//start=81,说明已经成功解出数独{return true;}else{bool ok = false;int row = start / 9;//根据此时方格的序号,计算出此方格的行和列int col = start % 9;if (board[row][col] == '.'){for (int i = 1; i <= 9; i++){if (isValid(row, col, i, board))//从1-9依次放入空格,并判断是否合法{board[row][col] = i + '0';//如果有数字合法,就写入该数字的字符ok = dfs(board, start + 1);//判断此方格的下一个方格是否成功写入if (!ok)//如果它的下一个方格是不合法的,说明它现在填入的数,不是正确的解,需回溯{board[row][col] = '.';//回溯}}}}else{ok = dfs(board, start + 1);}return ok;}}
};int main()
{/*vector<vector<char>>board = { vector<char>{'5','3','.','.','7','.','.','.','.'},vector<char>{'6','.','.','1','9','5','.','.','.'},vector<char>{'.','9','8','.','.','.','.','6','.'},vector<char>{'8','.','.','.','6','.','.','.','3'}, vector<char>{'4','.','.','8','.','3','.','.','1'}, vector<char>{'7','.','.','.','2','.','.','.','6'}, vector<char>{'.','6','.','.','.','.','2','8','.'}, vector<char>{'.','.','.','4','1','9','.','.','5'}, vector<char>{'.','.','.','.','8','.','.','7','9'}, };*/vector<vector<char>>blank(9, vector<char>(9,'.'));//创建一个9*9的空二维数组sudoku s(blank);s.create(50,blank);//创建50个空格的数独if (s.active){cout << "创建的数独为:" << endl;s.printBoard(blank);}elsecout << "数独表不合法,没有解!" << endl;s.dfs(blank, 0);//解数独函数if (s.active){cout << "此数独的解是:" << endl;s.printBoard(blank);}elsecout << "解题失败!" << endl;return 0;
}

数独的生成以及解答--回溯算法c++附详细代码相关推荐

  1. 用python求期望_Python——EM(期望极大算法)教学(附详细代码与注解)

    今天,我们详细的讲一下EM算法. 前提准备 Jupyter notebook 或 Pycharm 火狐浏览器或谷歌浏览器 win7或win10电脑一台 网盘提取csv数据 需求分析 实现高斯混合模型的 ...

  2. Python——EM(期望极大算法)实战(附详细代码与注解)(二)

    开始之前 各位朋友,大家好!针对上回讲的EM算法,有朋友反馈还是没弄清楚,今天,我再来详细的讲一下EM算法.请耐心食用本教程,滴滴滴~,上车! 前提准备 Jupyter notebook 或 Pych ...

  3. Python——EM(期望极大算法)实战(附详细代码与注解)(一)

    开始之前 各位朋友大家好!今天我将带大家撸EM算法代码,在撸之前(呵呵,可别乱想≧◔◡◔≦),我们首先讲清楚什么是EM算法?为什么要用EM算法?.在这里我简要的介绍一下,大家都知道极大似然估计吧(至少 ...

  4. c语言二分法_14个经典C语言算法你就不看一眼?(附详细代码)

    今天,给大家讲一讲,单片机常用的14个C语言算法(附详细代码)哟! 一.计数.求和.求阶乘等简单算法 此类问题都要使用循环,要注意根据问题确定循环变量的初值.终值或结束条件,更要注意用来表示计数.和. ...

  5. 基于MATLAB的三维数据插值拟合与三次样条拟合算法(附完整代码)

    目录 一. 三维插值 例题1 二. 高维度插值拟合 格式一 格式二 格式三 格式四 格式五 例题2 三. 单变量三次样条插值 例题3 例题4 四. 多变量三次样条插值 例题6 一. 三维插值 首先三维 ...

  6. 实现最小生成树Kruskal算法(附完整代码)

    实现最小生成树Kruskal算法(附完整代码) Kruskal算法是一种常见的计算最小生成树的算法.它的主要思想是将所有的边按照权值从小到大进行排序,并逐个加入到生成树中,如果加入后不会形成环,则保留 ...

  7. 【机器学习-分类】一句话+一张图说清楚朴素贝叶斯算法(附案例+代码)

    说在前面 同一个算法本身存在各种不同的变体,即各种改进版本.一句话+一张图并不能涵盖所有情况,只是尽量用通俗的语言介绍其中经典的算法版本.希望对某算法本身不了解的人看完能迅速get到该算法在干什么:二 ...

  8. ECG:机器学习之预处理算法与R波定位算法(附部分代码)

    ECG:机器学习之预处理算法与R波定位算法(附部分代码) 目前网上有关ECG信号处理的文章越来越多,说明这一块做的人也越来越多,但是网上的资源却很有限,而且很多资源都有一定的缺陷且不全.本文会对网上的 ...

  9. python重点知识归纳_一文了解机器学习知识点及其算法(附python代码)

    一文了解机器学习知识点及其算法(附python代码) 来源:数据城堡 时间:2016-09-09 14:05:50 作者: 机器学习发展到现在,已经形成较为完善的知识体系,同时大量的数据科学家的研究成 ...

最新文章

  1. python txt文件读写(追加、覆盖)
  2. poj 3026 (最小生成树)
  3. Vue.js环境搭建
  4. 我们并没有觉得MapReduce速度慢,直到Spark出现
  5. 好看的粉色树洞表白墙网站源码
  6. Win10微软帐户切换不回Administrator本地帐户的解决方法【亲测】
  7. 函数式编程会取代GoF设计模式吗?
  8. 0基础学python要多久-27岁0基础自学Python,多久可以找到工作?
  9. MySQL优化详解(五)——MySQL分库分表
  10. DaVinci Resolve Studio 17.4.1 Mac(达芬奇调色软件)
  11. 美国专家声讨物联网安全 面对攻击如纸糊
  12. 137.只出现一次的数字II
  13. 乐吾乐 Topology 全新优化1.0已经内测啦
  14. linux用户是什么意思,Linux中的./是什么意思
  15. webview的白屏,和硬件加速
  16. 转移APK从手机到PC和PC到手机
  17. 安卓开发中的重力感应传感器
  18. docker安装包安装
  19. cs231n-LSTM_Captions
  20. python期货外盘不间断交易_外盘期货模拟交易【最新版】_数据API_数据应用_股票行情接口/API-云市场-阿里云...

热门文章

  1. 大数据01:前置条件
  2. 爬取游戏优惠信息,并且将结果发送到邮箱
  3. selenium模拟鼠标键盘(一)
  4. vue props 属性值接受多个类型 _@jie
  5. 第三方代付入帐是什么意思
  6. php配置北京时间,php如何设置北京时间_后端开发
  7. opengl png图片 qt_Qt学习:三维绘图之OpenGL和Qt的结合(转)
  8. vue-3d-model:一个展示三维模型的 Vue 组件
  9. ESXI自动关机 ping值检测关机脚本
  10. 050002《马云说》读后感——勇者无畏