前段时间出差在外闲得无事看到一个数独问题。有三题,脑子不好使,只做出前两题。想想不如用程序来实现。
我先把题放出来大家有兴趣研究一下。

8

5

7

1

1

9

2

6

2

5

6

9

2

4

5

8

8

1

2

4

9

4

6

5

7

5

8

9

1

5

2

1

9

6

3

3

5

7

6

6

1

4

7

7

2

6

4

5

3

8

6

9

7

8

3

5

8

3

9

8

7

6

 

 

1

7

 

 

 

 

1

9

3

6

 

 

 

 

 

 

 

 

 

 

 

 

4

 

5

 

 

 

2

 

 

8

8

 

1

 

 

 

7

 

2

2

 

 

7

 

 

 

6

 

6

 

 

 

 

 

 

 

 

 

 

 

 

7

6

5

3

 

 

 

 

5

4

 

 

8

 

规则:
在9*9的格子中用1到9填满格子:
每一行都要用到1~9,位置不限;
每一列都要用到1~9,位置不限;
每3*3格子都要用到1~9,位置不限;

我的算法思想比较简单:穷举法,递归。
1、初始化:
 新建两个数组A[9,9],B[9,9],他们的初始值都一样。

public  static int[,,] A = new int[9,9,9];<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

public  static int[,] B = new int[9,9];

for(int i=0;i<9;i++)

for(int j=0;j<9;j++)

A[i,j] = 0;

A[0,1]=6;

A[0,4]=1;

A[0,5]=7;

………………

A[8,3]=5;

A[8,4]=4;

A[8,7]=8;

A[8,8]=6;

for(int m=0;m<9;m++)

for(int n=0;n<9;n++)

B[m,n] = 0;

B[0,1]=6;

B[0,4]=1;

B[0,5]=7;

………………

B[8,3]=5;

B[8,4]=4;

B[8,7]=8;

B[8,8]=6;

递归过程:

public void JudgeNumber(int x,int y)

{

if(x<9&&y<9)                                 //判断数组下标范围

{

if(A[x,y] == 0||A[x,y] != B[x,y])       //如果数组的值为零或者取得的值不等于B的值

{

for(int i=1;i<10;i++)

{

A[x,y] = i;                     //循环付值

if(Pass(x,y))                   //判断条件

{

if(Victory())              //成功

{

printShuzu();

return ;

}

if(y<8)                     //判断下一个数

JudgeNumber(x,y+1);

else

JudgeNumber(x+1,0);

}

}

A[x,y] = 0;                           //失败之后把值设为零,以便继续判断

}

else                                      //判断下一个数

{

if(y<8)

JudgeNumber(x,y+1);

else

JudgeNumber(x+1,0);

}

}

}

public <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />boolPass(int i,int j)

{

//判断横竖有无重复

for(int b=0;b<9;b++)

{

if(b!=i)

if(A[i,j] == A[b,j])

return false;

if(b!=j)

if(A[i,j] == A[i,b])

return false;

}

//判断*3有无重复

int q0 = (i/3)*3;

int k0 = (j/3)*3;

int q1 = (i/3+1)*3;

int k1 = (j/3+1)*3;

for(int q=q0;q<q1;q++)

for(int k=k0;k<k1;k++)

if(q!=i&&k!=j)

if(A[i,j] == A[q,k])

return false;

return true;

}

/// <summary>

/// 在Pass情况下如果整个数组无0表示成功求解

/// </summary>

/// <returns></returns>

public bool Victory()

{

bool ax=false;

for(int i=0;i<9;i++)

for(int j=0;j<9;j++)

{

if(  A[i,j] != 0)

ax =true;

else

return false;

}

return ax;

}

本算法的问题:
1.穷举取值过多。不必从1~9全部取
2.成功后在递归里面不能跳出。
对问题1的改进:
1.新建3维数组A[9,9,9]
2初始判断,获取该位置可取值的范围

for(int i=0;i<9;i++)

for(int j=0;j<9;j++)

{

int[] B = new int[9];

for(int d=0;d<9;d++)

B[d] = d+1;

if(A[i,j,0]==0)

{

for(int a=0;a<9;a++)

{

A[i,j,0] = B[a];

for(int b=0;b<9;b++)

{

if(b!=i)

if(A[i,j,0] == A[b,j,0])

B[a]=0;

if(b!=j)

if(A[i,j,0] == A[i,b,0])

B[a]=0;

}

int q0 = (i/3)*3;

int k0 = (j/3)*3;

int q1 = (i/3+1)*3;

int k1 = (j/3+1)*3;

for(int q=q0;q<q1;q++)

for(int k=k0;k<k1;k++)

if(q!=i&&k!=j)

if(A[i,j,0] == A[q,k,0])

B[a]=0;

A[i,j,0] = 0;

}

}

}

3.更改判断部分.

public void JudgeNumber(int x,int y)

{

if(x<9&&y<9)

{

if(A[x,y,0] == 0||A[x,y,0] != B[x,y])

{

for(int i=1;i<9;i++)//更改部分

{

if(A[x,y,i]!=0)//更改部分

{

A[x,y,0] = A[x,y,i];//更改部分

if(Pass(x,y))

{

if(Victory())

{

printShuzu();

//return ;

}

if(y<8)

JudgeNumber(x,y+1);

else

JudgeNumber(x+1,0);

}

}

}

A[x,y,0] = 0;

}

else

{

if(y<8)

JudgeNumber(x,y+1);

else

JudgeNumber(x+1,0);

}

}

}

转载于:https://www.cnblogs.com/wssmax/archive/2006/08/25/486229.html

一个数独问题的算法(已更新,提供一个简单算法,欢迎拍砖)相关推荐

  1. JAVA 计算圆的面积和周长: 创建一个圆Circle类。为该类提供一个变量r表示半径,一个常量PI表示圆周率; * 同时为该类提供两个方法:方法一用于求圆的面积,方法二用于求圆的周长;

      插一句嘴,现在扎扎实实地把这些基础地敲一遍,理解了,可能还是会忘记.但是你最后学习的是做题的思路,而不是单纯的记代码.代码忘了再回过头来看一遍就好了,思路是别人偷不走的.[2022-9] * 思路 ...

  2. 百度算法最新更新介绍之烽火算法

    现在算法还在持续升级迭代中,并将于近期扩大算法覆盖.为了能够更好的执行烽火算法,我们针对百度搜索下站点命中烽火算法的执行方法进行补充,规定算法观察期如下: 第三次及以上发现站点存在劫持问题,永久限制站 ...

  3. 分享一个自行开发的加强版swagger-ui,提供一个全新的api文档生成思路

    我前段时间开发的加强版swagger-ui. 这或许为swagger应该是一个什么样子, 提供了一个全新的思路. 文档缓存,即使服务器没开,仍然可以看文档. 文档注释增强,采用js注释写法,对前端人员 ...

  4. 干支纪年法简便算法_天干地支的简单算法

    大家在看古代字画的时候一定会发现 己亥 壬寅等干支纪年法,比如"岁在癸丑" 虽然现在的我们很少用干支纪年法了,但在历史考试题以及公务员考试题中难免会有计算天干地支的题目,就算不为了 ...

  5. mySQL:两表更新(用一个表更新另一个表)的SQL语句

    用一个表中的字段去更新另外一个表中的字段, MySQL 中有相应的 update 语句来支持,不过这个 update 语法有些特殊.看一个例子就明白了. create table student (s ...

  6. 金融安全算法介绍系列5——国密算法

    前言: 为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长. 1. 简介 国密即国家密码局认定的国产密码算法.主要有 SM1,SM2,S ...

  7. 简单算法的举例c语言,计算机科学与技术系C语言程序设计22简单算法举例.PPT

    计算机科学与技术系C语言程序设计22简单算法举例 第2章 程序的灵魂--算法 本章主要介绍算法的思想及算法的表示方法. 2.0 绪论 2.1 算法的概念 2.2 简单算法举例 2.3 算法的特性 2. ...

  8. 数独求解算法_我如何回到一个老问题,终于写了一个数独求解算法

    数独求解算法 by Ali Spittel 通过Ali Spittel 我如何回到一个老问题,终于写了一个数独求解算法 (How I came back to an old problem and f ...

  9. 提供一个基于.NET的加密/解密算法

    提供一个基于.NET SymmetricAlgorithm 类的.带私钥的加密/解密算法的包装类.使用方法: symmcrypto de = new SymmCrypto(SymmCrypto.Sym ...

最新文章

  1. 旷视推出鼻纹识别,用AI寻找丢失宠物
  2. 5 -- Hibernate的基本用法 -- 要点
  3. 31. 提取text.txt和text2.txt的文件内容,进行文本等号以后求和
  4. J2SE核心开发实战(二)——字符串与包装类
  5. CSDN中的如何转载博文
  6. 回文字符串(51Nod-1092)
  7. xampp for mac mysql_【XAMPP和Xampp For Mac哪个好用】XAMPP和Xampp For Mac对比-ZOL下载
  8. 交互进CMU后可以学计算机吗,转专业必看!申请计算机的先修课要求,以CMU为例...
  9. 清华ACL'22 | 一文读懂刘知远所在实验室18篇论文详情
  10. 【企业绩效考核系统】
  11. 基于51单片机的步进电机驱动程序
  12. 201671010402 词频统计软件项目报告
  13. 利用scrapy爬取美图录网站图集按模特姓名存储到本地(三)
  14. 打印纸张尺寸换算_常用纸张的尺寸大小对照表-纸张规格对照表.doc
  15. 服务器系统信息查询命令
  16. [FROM WOJ]#4317 谈笑风生
  17. VS Code 所选驱动器或UNC共享不存在或不可访问
  18. 今日头条校招2017.7.21编程3,PM、idea、程序员
  19. 谷歌翻译用不了,失效的最新解决方法之一
  20. GD32报错Feature(s) : RDI, FlashBP, FlashDL, JFlash, GDB

热门文章

  1. Python3 与 C# 并发编程之~ 进程篇
  2. URL转微信可识别的二维码
  3. 当导用模块与包的import与from的问题(模块与包的调用)
  4. Win32-Application的窗口和对话框
  5. Python-MongoDB的驱动安装、升级
  6. Error: Java heap space
  7. Sublime Text 3新建工程
  8. 【VBA编程】10.自定义集合
  9. 第二个Spring冲刺周期团队进展报告
  10. ActiveReports 报表应用教程 (8)---交互式报表之动态过滤