ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:74.63KB ,
资源ID:29377168      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/29377168.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(数独sudoku的生成与破解.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

数独sudoku的生成与破解.docx

1、数独sudoku的生成与破解数独(sudoku)的生成与破解一、 数独游戏的规则数独(sudoku),起源于瑞士,于1970 年代由美国的一家数学逻辑游戏杂志首先发表,当时名为Number Place。及后在日本大力推广下得以发扬光大,于1984 年取名“数独”,即“独立的数字”的省略,在一个99的方格中,有81个小方格组成,然后又分9个大块,每块由3x3的方格组成,就是中国的九宫阵。游戏规则:“九宫阵”是一个99的方阵,它是由九个“九宫格”(图中黑色实线围住的33的方阵)构成的,每个九宫格又是由九个小格子构成的,在每个小格子里面填上19中的数字,使得每个数字在“九宫阵”的每行、每列、每个九宫

2、格中均只出现一次。游戏开始前会有一些格子上写好了数,你需要在剩下的格子里填数,真到把所有格子填满,并且要求,任何一行或一列或者一个小九宫中没有相同的数字,当然你只能用19之间的9个数字。如下图就是一个数独游戏。题 目 答 案二、 数独(sudoku)的生成基本思路:为了保证生成的数独一定有解,就要先得到了一个完整的数独(可以想象所有满足条件的组合是很多的),然后从格子里面随机挖掉一些数字就可以了。那么如何得到一个完整数独呢?我们可以这样想先给每一行(或列)填入一个不同的数,然后用“数独破解”的方法去完成,这就OK了。步骤如下:1 在第i行 (i=08)随机找个格子mapij (j=08)填入本

3、行数i+1;2 用“数独求解”(见数独(sudoku)的生成)的方法产生一个完整数独;3 从81个格子里面随机挖去n个数字。三、 数独(sudoku)的破解我们可以想象每个格子可填入的数字是可以得知的,但这不是唯一的,应先填入哪个数字就是个问题,另外先填哪一个格子也是不确定的,那么如何开始填才最佳呢?这里我们需要引入一个概念格子的不确定度,一个格子可以填的数字的个数称为它的不确定度。所以我们需要用递归下面的做法:我们去寻找不确定度最小的格子;确定这个格子可以填的数字;填入一个数字后,递归。随着填上去数字增多,剩余空格上的不确定度也会降低,如果某个格子上的不确定度降到1,那这个格子可以先确定下来

4、,如果降到了0,哦,非常遗憾,在前面的填数中一定是填错了,你不得不回退。四、 唯一解的问题这里有一问题,我们需要的是我们生成的数独是否具有唯一解?是的,按上面数独生成的过程是不能保证的。为了保证数独有唯一解,应该从哪儿考虑呢?我的思路是:从完整数独中挖格子的过程中去分析。根据数独破解的方法,在破解过程中每次要寻找的最小不确定度的那个格子,如果每次找到的这个格子可填的数字都仅为个(最小不确定度为)时,那么得到的解一定唯一。这样就给我们启发,我们在挖格子时,每挖一个格子,也去检测最小不确定度的格子的不确定度。如果这个不确定度大于,则就要重新这次挖格子。另外也有可能挖遍所有的格子(程序中我设的上限是

5、81次)也没有合适解时,那么要中止这次操作,这时就要从重新生成一个数独。五、 游戏的难易程序这个问题我是这么考虑的,只要生成的数独中的空格数(blank)越多,那么就越难。所以在些程序中我设置三个级别:容易:blank=3335;中等:blank=3638;困难:blank=3941;六、 源程序#ifndef SUDOKU_RICK_0701_#define SUDOKU_RICK_0701_class CSudokuint map99;int blanks;int smod;int solves;int check(int,int,int*);void dfs();public:enumA

6、NY=0,ALL=1;CSudoku(int);CSudoku:CSudoku(int *data);void SudokuGenerator(int); / 随机生成数独,n越大越难void SudokuGenerator(int *data);/ 人工指定数独/virtual CSudoku();void display();/ 显示数独int resolve(int mod=ALL);/ 解数独void analyze(); ;#endif#include stdio.h#include stdlib.h#include time.h#include iostream#include i

7、omanip /要用到格式控制符using namespace std;CSudoku:CSudoku(int n)int j;j=rand()%3;blanks=n+j;SudokuGenerator(blanks); coutendl随机数独:endlendl;/cout(空格子数为blanks)endl;display();coutpress enter to continue! endl;getchar();getchar();while(1)cout % endl;cout % 请选择您的操作: % endl;cout %=% endl;cout % % endl;cout % 1.

8、 显示当前数独 % endl;cout % 2. 分析求解 % endl;cout % 3. 查看结果 % endl;cout % 4. 返 回 % endl;cout % % endl;cout % select;switch (select)case 1:coutendl当前随机数独: endl; display();coutpress enter to continue! endl;getchar();getchar();break;case 2:analyze(); break;case 3:coutendl显示结果: endl;resolve();coutpress enter to

9、 continue! endlendl;getchar();getchar();break;case 4: return;default:cout输入错误,请重新输入.endl;break;CSudoku:CSudoku(int *data)SudokuGenerator(data);coutendl已知数独为: endl; display();coutpress enter to continue! endl;getchar();getchar();analyze();void CSudoku:SudokuGenerator(int n)int i,j;int mark10;srand(ti

10、me(0);/每一行i产生一个随机位置(列j)并置为当前行值i+1,0=i,j=8。dofor(i=0;i9;+i)for(j=0;j9;+j)mapij=0;j=rand()%9;mapij=i+1;/display(); while(!resolve(ANY); /生成完整的随机Sudoku表格/ 挖窟窿for(int k=0;kn;+k)int tmp,flag=0,sum=1;do/ coutsum=sum81)SudokuGenerator(n); return;if (flag=1)mapij=tmp;doi=rand()%81;j=i%9;i=i/9;while (mapij=0

11、);tmp=mapij;mapij=0;flag=1;while (check(i,j,mark)1);void CSudoku:SudokuGenerator(int *data)int *pm=(int*)map;for(int i=0;i81;+i)pmi=datai;void CSudoku:display()printf(n);for(int i=0;i9;+i)for(int j=0;j0)if(j%3=0)printf( %d,mapij);elseprintf( %d,mapij);elseif(j%3=0)printf( );elseprintf( );printf(n);i

12、f (i!=8)if(i+1)%3=0)printf(n);elseprintf(n); printf(n);int CSudoku:resolve(int mod)smod=mod;if(mod=ALL)solves=0;dfs();return solves;else if(mod=ANY)trydfs();return 0;catch(int)return 1;return 0;int CSudoku:check(int y,int x,int *mark)int i,j,is,js,count=0;for(i=1;i=9;+i)marki=0;for(i=0;i9;+i)markmap

13、yi=1;for(i=0;i9;+i)markmapix=1;is=y/3*3;js=x/3*3;for(i=0;i3;+i)for(j=0;j3;+j)markmapis+ijs+j=1;for(i=1;i=9;+i)if(marki=0)count+;return count;void CSudoku:dfs()int i,j,im=-1,jm,min=10;int mark10;/ display();/求自由度最小的格mapimjmfor(i=0;i9;+i)for(j=0;j9;+j)if(mapij) /如果此格已填入数则看一下格。continue;int c=check(i,j,

14、mark); /如果此格空,则求其自由度。if(c=0) /已到结尾,没有空格了。 return;if(cmin)im=i;jm=j;min=c;if(im=-1) /若im=-1,则格子都填满。if(smod=ALL) /smod=ALL是求解过程。/printf(No. %d:n,+solves);display(); return; else if(smod=ANY) /smod=ANY是初始化过程。throw(1);check(im,jm,mark);for(i=1;i=9;+i)if(marki=0)mapimjm=i; /从小到大让第一个可填的数填入自由度最小的格。dfs();ma

15、pimjm=0; return;void CSudoku:analyze()while(1)cout % endl;cout % 请问你想做什么? % endl;cout %=% endl;cout % % endl;cout % 1. 查找最小不确定度的格子 % endl;cout % 2. 指定格子的可填数 % endl;cout % 3. 给指定格子填数 % endl;cout % 4. 显示当前数独 % endl;cout % 5. 查看结果 % endl;cout % 6. 返 回 % endl;cout % % endl;cout % select;switch(select)ca

16、se 1: /求不确定度最小的空格mapimjmint i,j,im=-1,jm,min=10;int mark10;for(i=0;i9;+i)for(j=0;j9;+j)if(mapij) /如果此格已填入数则看一下格。continue;int c=check(i,j,mark); /如果此格空,则求其不确定度。if(c=0)cout不能得到结果或已无空格子!自动返回! endl;return;if(cmin)im=i;jm=j;min=c;coutendl不确定度最小的格子为: im,jm 其可填的数的个数为: minendlendl;coutpress enter to continu

17、e! endl;getchar();getchar();break;case 2:int x,y;int mark10;coutendlxy;getchar();while (mapxy!=0)coutendl警告: 此格已经有数!请重新输入.endlendl;coutxy;getchar();int i,j,is,js,count=0;for(i=1;i=9;+i)marki=0;for(i=0;i9;+i)markmapxi=1;for(i=0;i9;+i)markmapiy=1;is=x/3*3;js=y/3*3;for(i=0;i3;+i)for(j=0;j3;+j)markmapis

18、+ijs+j=1;coutendl此格可填数为:;for(i=1;i=9;+i)if(marki=0)count+;coutsetw(4)i;coutendl;coutpress enter to continue! endl;getchar();break;case 3:int x,y;coutendlxy;coutmapxy;cout您填入的格为: mapx,y=mapxyendl;coutpress enter to continue! endl;getchar();getchar();break;case 4:coutendl当前随机数独: endl; display();coutpr

19、ess enter to continue! endl;getchar();getchar();break;case 5:coutendl显示结果: endl;resolve(); /没有输入参数,则默认为smod=ALL,见程序开始函数声明。coutpress enter to continue! endlendl;getchar();getchar();break;case 6:return;default:cout输入错误,请重新输入.endl;break;void main()int blanks;while(1)bool exit_f=true;coutendl;cout % end

20、l;cout % SUDOKU游戏 % endl;cout % 任二艳制作 % endl;cout %=% endl;cout % 1. 新游戏 % endl;cout % 2. 退 出 % endl;cout % select;switch (select)case 1: /开始新游戏while(exit_f)cout % endl;cout % 请选择游戏难度 % endl;cout %=% endl;cout % % endl;cout % 1. 简 单 % endl;cout % 2. 中 等 % endl;cout % 3. 困 难 % endl;cout % 4. 返 回 % endl;cout % % endl;cout % endl;/* coutendl请选择游戏难度: endl;cout= endl;cout1. 简 单endl;cout2. 中 等endl;cout3. 困 难endl;cout4. 解一个已知数独 endl;cout5. 退 出

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1