首先,来到这里的人应该都知道数独是什么。

那么,如果没有c++,你,在面对数独时会怎么做?

1.纯方法

1.摒除法:用数字去找单元内唯一可填空格,称为摒除法,数字可填唯一空格称为摒余解(隐性唯一解)。

就是通过某一个格子所在行与列和宫,确定当前格子上的数:

1 3 4
5(x) 5(x) 5(x) 5
5(x) 5(x) 5
5 5

根据已知三个“5”,排除一宫8个格子,得到“5”的掘除法

#ifndef SHUDUFA_H
#define SHUDUFA_H//定义头文件
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P; P ji[11];
int kuai[11][11],lie[11][11],hang[11][11],ma[11][11],k,mm[11][11];
inline int d(int pd,int x,int y) {if(pd==1) return x; else return y;}
inline int find(int num)
{int jinum=0;for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(ma[i][j]==num) ji[++jinum]=P(i,j);return jinum;
}//find(i)表示寻找数独上所有i数字的坐标并存于ji[i]中。
inline void biao_hui(int p,int x,int y,int val,int howk)
{hang[x][val]=p;lie[y][val]=p;kuai[howk][val]=p;mm[x][y]=1;ma[x][y]=p*val;k+=2*p-1;
}//biao_hui(p,x,y,val,howk)表示将数独第(x,y)个格子填入val且仅当p=1,标记(p=0时为回溯)
inline void does(int i1,int i2,int j1,int j2,int temp[11][11],int num,int howk)
{int sum=0,x,y; for(int i=i1;i<=i2;i++){for(int j=j1;j<=j2;j++){if(temp[i][j]) sum++;else x=i,y=j;}}if(sum==8&&kuai[howk][num]==0) biao_hui(1,x,y,num,howk);//宫内唯一解
}
inline void tian(int shu,int num)
{int temp[11][11];for(int j=1;j<=9;j++) for(int kk=1;kk<=9;kk++) temp[j][kk]=mm[j][kk];//记录那些位置没填,temp与mm此处功能一样。for(int i=1;i<=shu;i++){int x=ji[i].first,y=ji[i].second;for(int j=1;j<=9;j++) temp[x][j]=temp[j][y]=1;}//将数字num用于行列摒除法,再找宫内唯一解。for(int i=1;i<=3;i++){int xr=i*3,xl=xr-2;for(int j=1;j<=3;j++) does(xl,xr,(j-1)*3+1,j*3,temp,num,(i-1)*3+j);//找宫内唯一解并填入(上转does)}
}
inline void does2(int pd)//pd=1为求行内唯一解,pd=2为求列内唯一解
{if(pd==0){for(int i=1;i<=9;i++) tian(find(i),i);return;}for(int i=1;i<=9;i++){queue<int> q;int use[11],bu=0;memset(use,0,sizeof(use)); for(int j=1;j<=9;j++){if(!hang[d(pd,i,j)][d(pd,j,i)]){q.push(d(pd,j,i));use[d(pd,j,i)]=1;bu++;}}for(int j=1;j<=9;j++){if(ma[d(pd,i,j)][d(pd,j,i)]) continue;int num=(d(pd,i,j)-1)/3*3+(d(pd,j,i)-1)/3+1;for(int ki=1;ki<=9;ki++){if(use[ki]){int uu=0;for(int kk=1;kk<=9;kk++){if(use[kk]&&ki!=kk){if(kuai[num][kk]||hang[d(pd,i,j)][kk]||lie[d(pd,j,i)][kk]) uu++;}}if(uu==bu-1&&!kuai[num][ki]&&!hang[d(pd,i,j)][ki]&&!lie[d(pd,j,i)][ki]){bu--;use[ki]=0;biao_hui(1,d(pd,i,j),d(pd,j,i),ki,num);}}}}}
}
#endif 

2.余数法:用格位去找唯一可填数字,称为余数法,格位唯一可填数字称为唯余解(Naked Single)。(这简单,不用赘述)

3.直观法:不做任何记号,直接从数独的盘势观察线索,推论答案的方法。蒙圈......

4.候选数法就是删减等位群格位已出现的数字,将剩余可填数字填入空格做为解题线索的参考,可填数字称为候选数(Candidates,或称备选数)。(好恐怖)

2.c++思想:

1.暴力搜索

​
inline void dfs(int nx,int ny)
{if(ma[nx][ny]) {if(ny==9){if(nx<9) dfs(nx+1,1);else return;}else dfs(nx,ny+1);return;}for(int i=1;i<=9;i++){if(hang[nx][i]||lie[ny][i]||kuai[((nx-1)/3*3+(ny-1)/3+1)][i]) continue;biao_hui(1,nx,ny,i,((nx-1)/3*3+(ny-1)/3+1));if(k==81){print(ma);continue;}if(ny==9){if(nx<9) dfs(nx+1,1);else continue;}else dfs(nx,ny+1);biao_hui(0,nx,ny,i,((nx-1)/3*3+(ny-1)/3+1));}
}​

2.使用上述方法

#ifndef SHUDUFA_H
#define SHUDUFA_H
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P; P ji[11];
int kuai[11][11],lie[11][11],hang[11][11],ma[11][11],k,mm[11][11];
inline int d(int pd,int x,int y) {if(pd==1) return x; else return y;}
inline int find(int num)
{int jinum=0;for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(ma[i][j]==num) ji[++jinum]=P(i,j);return jinum;
}
inline void biao_hui(int p,int x,int y,int val,int howk)
{hang[x][val]=p;lie[y][val]=p;kuai[howk][val]=p;mm[x][y]=1;ma[x][y]=p*val;k+=2*p-1;
}
inline void does(int i1,int i2,int j1,int j2,int temp[11][11],int num,int howk)
{int sum=0,x,y; for(int i=i1;i<=i2;i++){for(int j=j1;j<=j2;j++){if(temp[i][j]) sum++;else x=i,y=j;}}if(sum==8&&kuai[howk][num]==0) biao_hui(1,x,y,num,howk);
}
inline void tian(int shu,int num)
{int temp[11][11];for(int j=1;j<=9;j++) for(int kk=1;kk<=9;kk++) temp[j][kk]=mm[j][kk];for(int i=1;i<=shu;i++){int x=ji[i].first,y=ji[i].second;for(int j=1;j<=9;j++) temp[x][j]=temp[j][y]=1;}for(int i=1;i<=3;i++){int xr=i*3,xl=xr-2;for(int j=1;j<=3;j++) does(xl,xr,(j-1)*3+1,j*3,temp,num,(i-1)*3+j);}
}
inline void does2(int pd)
{if(pd==0){for(int i=1;i<=9;i++) tian(find(i),i);return;}for(int i=1;i<=9;i++){queue<int> q;int use[11],bu=0;memset(use,0,sizeof(use)); for(int j=1;j<=9;j++){if(!hang[d(pd,i,j)][d(pd,j,i)]){q.push(d(pd,j,i));use[d(pd,j,i)]=1;bu++;}}for(int j=1;j<=9;j++){if(ma[d(pd,i,j)][d(pd,j,i)]) continue;int num=(d(pd,i,j)-1)/3*3+(d(pd,j,i)-1)/3+1;for(int ki=1;ki<=9;ki++){if(use[ki]){int uu=0;for(int kk=1;kk<=9;kk++){if(use[kk]&&ki!=kk){if(kuai[num][kk]||hang[d(pd,i,j)][kk]||lie[d(pd,j,i)][kk]) uu++;}}if(uu==bu-1&&!kuai[num][ki]&&!hang[d(pd,i,j)][ki]&&!lie[d(pd,j,i)][ki]){bu--;use[ki]=0;biao_hui(1,d(pd,i,j),d(pd,j,i),ki,num);}}}}}
}
#endif 

3.完整代码:

cpp:

#include"bits/stdc++.h"
#include"shudufa.h"
#include"reawri.h"
using namespace std;
inline void dfs(int nx,int ny)
{if(ma[nx][ny]) {if(ny==9){if(nx<9) dfs(nx+1,1);else return;}else dfs(nx,ny+1);return;}for(int i=1;i<=9;i++){if(hang[nx][i]||lie[ny][i]||kuai[((nx-1)/3*3+(ny-1)/3+1)][i]) continue;biao_hui(1,nx,ny,i,((nx-1)/3*3+(ny-1)/3+1));if(k==81){print(ma);continue;}if(ny==9){if(nx<9) dfs(nx+1,1);else continue;}else dfs(nx,ny+1);biao_hui(0,nx,ny,i,((nx-1)/3*3+(ny-1)/3+1));}
}
inline void work()
{int t=0;string a,b;while(k<81){if(t==0) a="(区域确定式)",b="(横线确定式)";if(t==1) a="(横线确定式)",b="(竖线确定式)";int lastk=k;for(int i=0;i<=t;i++) does2(t);if(lastk==k){print(ma);cout<<("仅有"+a+"法不可行\n加入法"+b+"\n");t++;}if(t>2) break;}cout<<"不正常方法:开始搜索......\n";dfs(1,1);
}
int main()
{read();work();return 0;
} 

shudufa.h:

#ifndef SHUDUFA_H
#define SHUDUFA_H
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P; P ji[11];
int kuai[11][11],lie[11][11],hang[11][11],ma[11][11],k,mm[11][11];
inline int d(int pd,int x,int y) {if(pd==1) return x; else return y;}
inline int find(int num)
{int jinum=0;for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(ma[i][j]==num) ji[++jinum]=P(i,j);return jinum;
}
inline void biao_hui(int p,int x,int y,int val,int howk)
{hang[x][val]=p;lie[y][val]=p;kuai[howk][val]=p;mm[x][y]=1;ma[x][y]=p*val;k+=2*p-1;
}
inline void does(int i1,int i2,int j1,int j2,int temp[11][11],int num,int howk)
{int sum=0,x,y; for(int i=i1;i<=i2;i++){for(int j=j1;j<=j2;j++){if(temp[i][j]) sum++;else x=i,y=j;}}if(sum==8&&kuai[howk][num]==0) biao_hui(1,x,y,num,howk);
}
inline void tian(int shu,int num)
{int temp[11][11];for(int j=1;j<=9;j++) for(int kk=1;kk<=9;kk++) temp[j][kk]=mm[j][kk];for(int i=1;i<=shu;i++){int x=ji[i].first,y=ji[i].second;for(int j=1;j<=9;j++) temp[x][j]=temp[j][y]=1;}for(int i=1;i<=3;i++){int xr=i*3,xl=xr-2;for(int j=1;j<=3;j++) does(xl,xr,(j-1)*3+1,j*3,temp,num,(i-1)*3+j);}
}
inline void does2(int pd)
{if(pd==0){for(int i=1;i<=9;i++) tian(find(i),i);return;}for(int i=1;i<=9;i++){queue<int> q;int use[11],bu=0;memset(use,0,sizeof(use)); for(int j=1;j<=9;j++){if(!hang[d(pd,i,j)][d(pd,j,i)]){q.push(d(pd,j,i));use[d(pd,j,i)]=1;bu++;}}for(int j=1;j<=9;j++){if(ma[d(pd,i,j)][d(pd,j,i)]) continue;int num=(d(pd,i,j)-1)/3*3+(d(pd,j,i)-1)/3+1;for(int ki=1;ki<=9;ki++){if(use[ki]){int uu=0;for(int kk=1;kk<=9;kk++){if(use[kk]&&ki!=kk){if(kuai[num][kk]||hang[d(pd,i,j)][kk]||lie[d(pd,j,i)][kk]) uu++;}}if(uu==bu-1&&!kuai[num][ki]&&!hang[d(pd,i,j)][ki]&&!lie[d(pd,j,i)][ki]){bu--;use[ki]=0;biao_hui(1,d(pd,i,j),d(pd,j,i),ki,num);}}}}}
}
#endif 

reawri.h:

#ifndef REAWRI_H
#define REAWRI_H
#include"shudufa.h"
#include<bits/stdc++.h>
using namespace std;
inline void print(int mmm[11][11])
{for(int i=1;i<=9;i++){for(int j=1;j<=9;j++) cout<<mmm[i][j]; cout<<endl;}cout<<endl;
}
inline void read()
{for(int i=1;i<=9;i++){for(int j=1;j<=9;j++){cin>>ma[i][j];if(ma[i][j]) {int num=(i-1)/3*3+(j-1)/3+1;biao_hui(1,i,j,ma[i][j],num);}}}
}
#endif

C++实现数独(附带过程)相关推荐

  1. 使用C#编程解决数独求解过程(从图片识别到数独求解)第二篇

    这是在C#开发平台上借助Emgucv和Tessnet实现的,通过图像识别的方式求解手机app中"数独"应用中的九宫格. 预处理:emgucv-windesktop 3.1.0.22 ...

  2. 基于C++和QT实现的简单数独游戏软件

    资源下载地址:https://download.csdn.net/download/sheziqiong/85660211 一.实验题目与要求 本次实验主要内容是实现一个简单的数独软件,具体要求如下: ...

  3. C语言简单数独游戏终盘生成

    前言 这一篇文章介绍的是移动变换法,有详细的移动变化法的图文解析,在文末有完整的可用于查看移动变换法生成数独终盘过程的代码 实现思路 移动变换法这一方法是很简单的一种方法,实现起来也比较容易,但同时它 ...

  4. 【习题·搜索】[NOIP2009]靶型数独(搜索+剪枝+位运算优化)

    题目 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士拿出了他最近发明的&quo ...

  5. 软件工程大作业——数独游戏

    软件工程大作业--数独游戏1 一.PSP表格 二.问题分析 三.系统设计 四.具体实现 五.单元测试 六.程序性能及质量分析 七.GUI 八.总结 代码地址:https://github.com/fr ...

  6. cobbler 无人值守-安装

    环境准备 准备两台主机,如centos6和centos7 centos7当作server服务器 关闭selinux 关闭防火墙 安装 cobbler包光盘里是没有的,要配置epel源,这里就说怎么配置 ...

  7. 怎么用纸做圆形的盒子_如何培养孩子逻辑思维能力?抓住0-8岁关键期,聪明的家长这样做...

    最近和朋友聊天,他特别苦恼和纳闷:我的孩子幼儿园和刚进入小学时成绩总是名列前茅,怎么越往后成绩越差,这是为什么呢? 这种现象还是挺经常出现的,幼儿园和小学1-3年级阶段,孩子努力用功是可以取得好成绩的 ...

  8. 幼儿抽象逻辑思维举例_孩子逻辑思维能力有多重要?巧用生活小游戏,培养好了娃受益终身...

    最近和朋友聊天,他特别苦恼和纳闷:我的孩子幼儿园和刚进入小学时成绩总是名列前茅,怎么越往后成绩越差,这是为什么呢? 这种现象还是挺经常出现的,幼儿园和小学1-3年级阶段,孩子努力用功是可以取得好成绩的 ...

  9. 2019软件工程第三次作业

    2019软件工程第三次作业 数独游戏 戳这里进入Github项目 第一眼看到要做数独的时候,脑海里的第一反应就是用深搜.现在好了,确定了算法,接下来就是要去实现它,可是对于将近半年没写过深搜的我要写一 ...

最新文章

  1. GaussianBlur函数
  2. 右键删除选中的行总提示rowIndex
  3. 读书记:asp.net2.0电子商务开发实战
  4. 给lnmp一键包中的nginx安装openresty的lua扩展
  5. 自动采集壁纸的微信小程序
  6. Java实现单词树(trie)
  7. Zend Framework实例教程三
  8. IOCP的Demo及说明
  9. Python装饰器的原理与应用
  10. 河北2021高考成绩查询具体时间,2021河北高考时间具体安排表
  11. 2020五一建模:C题 饲料混合加工问题 题解
  12. 【LED灯屏控制器】国产FPGA之 AG10KSDE176 初探(1)
  13. kvm虚拟机管理工具列表
  14. php天籁吉他乐器介绍网站系统
  15. 《全民学乒乓》学习笔记
  16. 3 继续测试一下 esp_tunnel 用 racoon协商 用setkey设置 spd
  17. 深度学习超分辨率综述阅读笔记(翻译)
  18. 魔众EDM邮件营销系统 v1.0.0 专业的EDM邮件营销系统
  19. Guides-旅游类App原型分享
  20. 复旦大学计算机学院肖江,【学术报道】复旦大学肖江教授应邀来我校学术交流...

热门文章

  1. WPF中ListView排序实现(2022.12.25有更新)
  2. 华为交换机ssh思科交换机_如何在思科交换机上配置SSH远程登录
  3. capsule 安装_Capsule:开源的 JVM 应用部署工具
  4. 台湾通行证识别易语言代码
  5. spark on k8s中指定spark.executor.instances为3,却没有启动executor的pod分析与解决
  6. 正月初五迎财神抢红包发红包!红包封面不能少!红包财源滚滚快来领取
  7. 为Notepad++安装Emmet插件
  8. Python 实现文本解析器
  9. 2021-2022年十类(30+)热门资质证书汇总分享,
  10. delphi mysql 图片_如何读取delphi数据库中的图片