数独这个游戏大家都知道吧:玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3×3)内的数字均含1-9,不重复。

为了更好的区分已填和未填的格子,未填的格子用0表示!!

1.输入

int a[11][11];
int alltheanswer;//所有的解
int wanttheanswer;//期望得到的解数
int main()
{printf("请输入9*9的数独:\n");for(int i=1; i<=9; i++)for(int j=1; j<=9; j++)scanf("%d",&a[i][j]);printf("请输入你期望得到的解数:\n");cin>>wanttheanswer;
}

2.检查每一行是否有重复

bool checkx(int x) {//x为第几行 for(int i=1; i<=9; i++) {if(a[x][i]==0)continue;for(int j=1; j<i; j++)if(a[x][i]==a[x][j])return false;}return true;
}

3.检查每一列是否有重复

bool checky(int y) { //y为第几列for(int i=1; i<=9; i++) {if(a[i][y]==0)continue;for(int j=1; j<i; j++)if(a[i][y]==a[j][y])return false;}return true;
}

4.检查每一个九宫格是否满足条件

bool jggfz(int x,int y) {//辅助判断 for(int i=x; i<x+3; i++) {for(int j=y; j<y+3; j++) {if(a[i][j]==0)continue;for(int ii=x; ii<i; ii++) {for(int jj=y; jj<y+3; jj++) {if(a[i][j]==a[ii][jj])return false;}}}}return true;
}
bool jgg() { //九宫格判断if(jggfz(1,1)==false)return false;if(jggfz(4,1)==false)return false;if(jggfz(7,1)==false)return false;if(jggfz(1,4)==false)return false;if(jggfz(4,4)==false)return false;if(jggfz(7,4)==false)return false;if(jggfz(1,7)==false)return false;if(jggfz(4,7)==false)return false;if(jggfz(7,7)==false)return false;return true;
}

5.进行搜索与回溯

void dfs(int na,int nb) { //第几行第几个if(na==10) {if(jgg()==true) {alltheanswer++;if(wanttheanswer>=alltheanswer) {printf("\n");printf("此题解%d\n",alltheanswer);for(int i=1; i<=9; i++) {for(int j=1; j<=9; j++) {if((i==4&&j==1)||(i==7&&j==1))printf(" -------------------\n");else if(j==4||j==7)printf("|");printf("%2d",a[i][j]);}printf("\n");}}return;}}if(a[na][nb]!=0) {//特殊情况int nna=na,nnb=nb;if(nb==9)na++,nb=1;elsenb++;dfs(na,nb);na=nna,nb=nnb;return;}for(int i=1; i<=9; i++) {a[na][nb]=i;if(checkx(na)==false||checky(nb)==false||jgg()==false) {a[na][nb]=0;continue;}int nna=na,nnb=nb;if(nb==9)na++,nb=1;elsenb++;dfs(na,nb);na=nna,nb=nnb;a[nna][nnb]=0;}
}

【整体代码如下】


#include<bits/stdc++.h>//数独
using namespace std;
int a[11][11];
int alltheanswer;
int wanttheanswer;
bool checkx(int x) {//每行是否会重复for(int i=1; i<=9; i++) {if(a[x][i]==0)continue;for(int j=1; j<i; j++)if(a[x][i]==a[x][j])return false;}return true;
}
bool checky(int y) { //每列是否会重复for(int i=1; i<=9; i++) {if(a[i][y]==0)continue;for(int j=1; j<i; j++)if(a[i][y]==a[j][y])return false;}return true;
}
bool jggfz(int x,int y) {//根据jgg中输入的行和列,判断这个九宫格是否会发生冲突for(int i=x; i<x+3; i++) {for(int j=y; j<y+3; j++) {if(a[i][j]==0)continue;for(int ii=x; ii<i; ii++) {for(int jj=y; jj<y+3; jj++) {if(a[i][j]==a[ii][jj])return false;}}}}return true;
}
bool jgg() { //判断每个九宫格是否会发生冲突,具体看函数jggfz()if(jggfz(1,1)==false)return false;if(jggfz(4,1)==false)return false;if(jggfz(7,1)==false)return false;if(jggfz(1,4)==false)return false;if(jggfz(4,4)==false)return false;if(jggfz(7,4)==false)return false;if(jggfz(1,7)==false)return false;if(jggfz(4,7)==false)return false;if(jggfz(7,7)==false)return false;return true;
}
void dfs(int na,int nb) { //第几行第几个if(na==10) {if(jgg()==true) {alltheanswer++;if(wanttheanswer>=alltheanswer) {printf("\n");printf("此题解%d\n",alltheanswer);for(int i=1; i<=9; i++) {for(int j=1; j<=9; j++) {if((i==4&&j==1)||(i==7&&j==1))printf(" -------------------\n");else if(j==4||j==7)printf("|");printf("%2d",a[i][j]);}printf("\n");}}return;}}if(a[na][nb]!=0) {//这个位置的数已经填过了,直接填下一个数int nna=na,nnb=nb;if(nb==9)na++,nb=1;elsenb++;dfs(na,nb);na=nna,nb=nnb;return;}for(int i=1; i<=9; i++) {//选择填什么数字:1~9a[na][nb]=i;if(checkx(na)==false||checky(nb)==false||jgg()==false) {//检查这一行,这一列,这一个九宫格填这个数字是否发生冲突a[na][nb]=0;continue;}int nna=na,nnb=nb;//保存开始的行,列//更新na,nb为下一个要填的位置//普通:nb+1//应为nb的范围为1~9所以当nb=9时就是要填下一行了,所以na+1if(nb==9)na++,nb=1;elsenb++;dfs(na,nb);//填下一个数字na=nna,nb=nnb;//将开始的值返回a[nna][nnb]=0;}
}
int main() {printf("请输入9*9的数独:\n");for(int i=1; i<=9; i++)for(int j=1; j<=9; j++)scanf("%d",&a[i][j]);printf("请输入你期望得到的解数:\n");cin>>wanttheanswer;dfs(1,1);printf("此题所有解为:%d\n\n",alltheanswer);printf("--------------------------\n");printf("按Enter键退出\n");char a;//等待退出a=getchar();a=getchar();return 0;
}

代码测试:

不方便执行c++代码的这边是.exe文件的下载地址:

链接:https://pan.baidu.com/s/1aA0ahZpZx2x0bVxjvSmL7g 
提取码:1234

(已经达到期望题解,答案不输出但一直输出换行的BUG已修复)

但是,感觉这个代码运行的速度太慢了,所以我优化了一下,上面的代码比较好理解

代码如下:

#include<bits/stdc++.h>//数独
using namespace std;
int a[11][11];
int b[11];//每行已知数最多
int bid[11];//b的id
int bbid;//bid第几个
int c[11];//每列已知数最多
int cid[11];//c的id
int ccid;//cid第几个
int maxx;
int alltheanswer;
int wanttheanswer;
bool checkx(int x) {//x为第几行for(int i=1; i<=9; i++) {if(a[x][i]==0)continue;for(int j=1; j<i; j++)if(a[x][i]==a[x][j])return false;}return true;
}
bool checky(int y) { //y为第几列for(int i=1; i<=9; i++) {if(a[i][y]==0)continue;for(int j=1; j<i; j++)if(a[i][y]==a[j][y])return false;}return true;
}
bool jggfz(int djgg) {int x,y;if(djgg==1)x=1,y=1;else if(djgg==2)x=1,y=4;else if(djgg==3)x=1,y=7;else if(djgg==4)x=4,y=1;else if(djgg==5)x=4,y=4;else if(djgg==6)x=4,y=7;else if(djgg==7)x=7,y=1;else if(djgg==8)x=7,y=4;elsex=7,y=7;for(int k=1; k<=9; k++) {bool f=false;for(int i=x; i<x+3; i++) {for(int j=y; j<y+3; j++) {if(a[i][j]==0)continue;if(a[i][j]==k&&f==false)f=true;else if(a[i][j]==k)return false;}}}return true;
}
void dfs(int na,int nb) { //第几行第几个if(bbid==10) {alltheanswer++;if(wanttheanswer>=alltheanswer) {printf("\n");printf("此题解%d\n",alltheanswer);for(int i=1; i<=9; i++) {for(int j=1; j<=9; j++) {if((i==4&&j==1)||(i==7&&j==1))printf(" -------------------\n");else if(j==4||j==7)printf("|");printf("%2d",a[i][j]);}printf("\n");}}return;}if(a[na][nb]!=0) {int nna=na,nnb=nb,bbidd=bbid,ccidd=ccid;if(ccid==9)bbid++,ccid=1;elseccid++;dfs(bid[bbid],cid[ccid]);na=nna,nb=nnb,bbid=bbidd,ccid=ccidd;return;}for(int i=1; i<=9; i++) {a[na][nb]=i;int xx,yy;int djgg=(na-1)/3*3+(nb-1)/3+1;//第几个九宫格if(checkx(na)==false||checky(nb)==false||jggfz(djgg)==false) {a[na][nb]=0;continue;}int nna=na,nnb=nb,bbidd=bbid,ccidd=ccid;if(ccid==9)bbid++,ccid=1;elseccid++;dfs(bid[bbid],cid[ccid]);na=nna,nb=nnb,bbid=bbidd,ccid=ccidd;a[nna][nnb]=0;}
}
int main() {printf("请输入9*9的数独:\n");for(int i=1; i<=9; i++) {for(int j=1; j<=9; j++) {scanf("%d",&a[i][j]);if(a[i][j]!=0)b[i]++;if(a[j][i]!=0)c[i]++;}}//哪行已知数最多从哪行开始填,哪列已知数多从那列开始填for(int i=1; i<=9; i++)bid[i]=i,cid[i]=i;for(int i=1; i<=9; i++) {for(int j=1; j<=9-i; j++) {if(b[j]<b[j+1])swap(b[j],b[j+1]),swap(bid[j],bid[j+1]);if(c[j]<c[j+1])swap(c[j],c[j+1]),swap(cid[j],cid[j+1]);}}printf("请输入你期望得到的解数:\n");cin>>wanttheanswer;dfs(bid[++bbid],cid[++ccid]);printf("此题所有解为:%d\n\n",alltheanswer);printf("--------------------------\n");printf("按Enter键退出\n");char a;//等待退出a=getchar();a=getchar();return 0;
}

代码测试:

因为搜索的顺序不一样,所以解的输出顺序可能和第一个代码不一样。

下面是这个代码的.exe文件的下载地址:

链接:https://pan.baidu.com/s/1rWA2mxVqp4DxJp4lh73Z9w 
提取码:1234

数独求解:用c++做一个数独求解的程序(附源代码和.exe文件)相关推荐

  1. 用 JS 做一个数独游戏(二)

    用 JS 做一个数独游戏(二) 在 上一篇博客 中,我们通过 Node 运行了我们的 JavaScript 代码,在控制台中打印出来生成好的数独终盘.为了让我们的数独游戏能有良好的体验,这篇博客将会为 ...

  2. python大作业数独_python做一个数独小游戏

    最近看了下python的一些知识,在这里记载一下. 1.首先是安装,在官网下载最新的版本3.6,安装的时候要注意在下面勾选上ADD TO PATH,安装的时候会自动写入到环境变量里面,如果没有勾选,可 ...

  3. 臻好黄金百香果苗做一个有脑子的程序员

    程序员是最理性的一个群人,除非面对电子产品的时. 程序员是一群高智商的群体,唯一的缺点就是发际线总是很难防守. 程序员是一群情商比较低的人群,常常看到程序员仅仅因为对技术的理解不同而大吵起来. 程序员 ...

  4. 争取做一个良性循环的程序员

    争取做一个良性循环的程序员,莫让恶性循环上身. 以下阐述仅仅的是个人的想法和意见!觉得有说的不对的地方您老人家可以随手关掉页面,顺便可以嘀咕一句(太水了,简直就是胡诌)!^_^ 一:需求与概要 一点1 ...

  5. 要怎么样做一个合格点的程序猿呢?

    要怎么样做一个合格点的程序猿呢? 把编程当做人生来看,磨刀不误砍柴工.看完设计模式以后,就算以后设计不出很精巧的模式,我也会先仔细想好,仔细研究透了需求,分析透了设计,再写代码,不然的话,后期的维护, ...

  6. 用C++做一个特小型恶意程序

    用C++做一个特小型恶意程序 #include <windows.h> #include <ctime> #include <cstdlib> using name ...

  7. [xia谈]做一个爱家的程序员

    我说我要买车的话就买BYD F0,轻巧,油耗低,简单.我老婆说我现在是这种想法,过几年就不这样想了,那个时候会喜欢大气的车,那是男人成功的标志. "我现在就很成功了!"我老婆笑我& ...

  8. ai绘画知识:做一个AI绘画小程序要花多少钱?

    ai绘画彻底火了,赛道一度火过了当年的短视频行业.目前AI绘画以依托于微信小程序为主.如数画.意间.无界版图.灵境.6PEN.盗梦师这些AI绘画小程序清一色是10月份后上线.仅仅两月时间,但都已圈的用 ...

  9. 微店铺是什么?做一个微店铺小程序的流程

    微店铺是什么? 微店铺是指在微信平台上主要通过微信小程序方式创建的一个在线店铺.微店铺和传统的电商平台相比,具有更低的成本.更好的管理.更便捷的体验等优点,同时也有利于商家与用户之间的互动和沟通. 如 ...

最新文章

  1. java技术培训之File类中常用的构造方法
  2. 神器!3小时复现 Alexnet 和 word2vec!
  3. LBP特征学习(附python实现)
  4. mkisofs简单定制linux iso
  5. 一道关于信号量的问题
  6. 【算法数据结构Java实现】时间复杂度为O(n)的最大和序列
  7. 论文笔记 《Selective Search for Object Recognition》
  8. 大学计算机专业高考听力,高考英语听力测试对考生听力策略反拨作用的研究
  9. python 元组的一点问题
  10. mysql模式匹配详解_MySQL SQL模式匹配
  11. 《构建之法》(第一、二、十六章)读书笔记
  12. 基于Vue的移动端h5页面的电子签名
  13. 计算机网络波特率定义,传输速率——比特率和波特率
  14. 什么是elastic-job(持续更新)
  15. HTML怎么消除链接下划线,HTML怎么去掉超链接的下划线
  16. 有好看的女生用的黑色壁纸吗?
  17. 软件开发流程与初始软件测试
  18. 无线功率传输(WPT)及相关标准(包括Qi)
  19. Android studio中.9图片的含义及制作教程
  20. uboot usb启动

热门文章

  1. 主成分分析(PCA)原理与故障诊断(SPE、T^2以及结合二者的综合指标)-MATLAB实现
  2. 微信屏蔽网页的依据是什么?
  3. 斗拱展开面积表_古建筑斗拱换算问题
  4. 对随机变量值域的思考
  5. ROS用python编写订阅者和发布者(使用存放在其他package的自定义msg文件)
  6. 深圳宝安周边公司出行团建户外一日游
  7. 自考学历和成考学历哪个更高一些 有啥区别
  8. 个人或企业网站建设备案不备案有区别?如何备案?
  9. C语言编写可以实现malloc() free()功能的函数(空间/时间复杂度低)
  10. 为将来而记下的过去——扭曲的爱,病态的教育