惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
人人都是产品经理
人人都是产品经理
Spread Privacy
Spread Privacy
IT之家
IT之家
F
Fortinet All Blogs
GbyAI
GbyAI
T
Threat Research - Cisco Blogs
月光博客
月光博客
WordPress大学
WordPress大学
V
Vulnerabilities – Threatpost
G
GRAHAM CLULEY
酷 壳 – CoolShell
酷 壳 – CoolShell
MyScale Blog
MyScale Blog
小众软件
小众软件
AI
AI
云风的 BLOG
云风的 BLOG
Jina AI
Jina AI
博客园 - 【当耐特】
T
Tailwind CSS Blog
Recorded Future
Recorded Future
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
Schneier on Security
Schneier on Security
Engineering at Meta
Engineering at Meta
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
T
The Exploit Database - CXSecurity.com
大猫的无限游戏
大猫的无限游戏
PCI Perspectives
PCI Perspectives
K
Kaspersky official blog
U
Unit 42
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Webroot Blog
Webroot Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
A
About on SuperTechFans
Stack Overflow Blog
Stack Overflow Blog
N
News and Events Feed by Topic
MongoDB | Blog
MongoDB | Blog
C
CERT Recently Published Vulnerability Notes
Security Latest
Security Latest
爱范儿
爱范儿
L
LangChain Blog
V
Visual Studio Blog
W
WeLiveSecurity
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
C
Cisco Blogs
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - 胡敏

WebSharp 3.0(个人修订版)全代码,WebSharp 的作者已经抛弃它了吗?(一个国产ORM框架) 从追MM谈Java的23种设计模式 - 太经典了,转到自己的BLOG上收藏着先 利用.net创建安全COM控件 AutoCAD二次开发之创建菜单 我的家——三维地图 生活在垃圾网络中,我们该怎么办? vs.net 2005 中文版下载 c#调用des64.dll进行加密解密 - 胡敏 - 博客园 MapXtreme 2004 6.2 中文版破解文件及安装方法(已经不提供下载) 提供MapXtreme 2004 6.2 NCP破解文件及安装方法(已经不能提供了,等待破解最新的吧) 爆笑经典签名 一句话经典笑话 MapXtreme2004新手资料续 MapXtreme2004初学者资料(整理) 移动用户查询手机开通的服务 使用 Rational XDE for .net建模和设计数据库(原创) 自己动手注册xde for .net帮助 如何得到别人收藏夹里的网址 十种你不知道的东西,绝对经典(如果你知道就不用点了,该休息了)(转)
一个数独问题的算法(已更新,提供一个简单算法,欢迎拍砖)
胡敏 · 2006-08-25 · via 博客园 - 胡敏

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

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];

         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 bool Pass(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);

                   }

              }

         }