数独这个游戏大家都知道吧:玩家需要根据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. stl string常用函数
  2. YOLOv4重磅发布,五大改进,二十多项技巧实验,堪称最强目标检测万花筒
  3. 【kafka】Kafka Connect中的增量协同平衡
  4. 游戏中用户升级的设计
  5. good nice fine well区别
  6. Acrobat Pro DC 教程,如何将 PDF 导出为 Microsoft Office 格式?
  7. Bootstrap页面布局4 - 嵌套布局
  8. inceptor游标使用及优化
  9. 《黑客攻防技术宝典:系统实战篇(第2版)》目录
  10. dmz和端口映射_DMZ和端口映射有何区别
  11. Android 微信、QQ、微博分享问题汇总
  12. 从社交网络图的edgelist得到adj
  13. 北美票房:《触不可及》惊喜夺冠
  14. 1467: 平面点排序(一)(结构体专题)
  15. http下载异常_荏苒项目二:配置(日志,异常,数据库,前端,跨域CORS)
  16. 《Loy解说Eureka服务端源码(一)》
  17. 工具-如何屏蔽浏览器中的广告(Adblock Plus(广告屏蔽器))
  18. scratch零基础
  19. 计算机专业英语形成型考核册,电大资源网《人文英语3》形成性考核册作业题目和答案2018年...
  20. 用Python做了一个猫狗识别系统~

热门文章

  1. wsappx导致系统崩溃
  2. Windows 10任务栏中托盘区(通知区域)图标消失的解决方法
  3. Unit Test and Integration Test
  4. Python 最简单的微信刷屏
  5. 如何克服自己懒惰的坏习惯?
  6. Java项目:考试在线报名管理系统(java+SSM+HTML+JS+jsp+mysql)
  7. 什么是Ntrip?Ntrip协议简介
  8. 新闻页面数据分页and添加新闻评论
  9. python判断字符串是字母 数字 大小写
  10. 11矩阵空间、秩1矩阵和小世界图