你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
用C语言模拟数独的人工解题思路(一)
 

摘 要 2006年首届世界数独大赛决赛题目为例,说明用C语言模拟数独的人工解题思路。介绍了唯一法、排除法及尝试法三种解题方法。C语言模拟数独的人工解题思路,有利于学习C语言及相应的编程技巧,尝试着把人的思维方式转化成相应的计算机程序,便于人工智能方面的研究。试验验证了程序的正确性。

关键词 数独; C语言; 人工解题; 候选数

 

 

一、引言

数独是一种源自18世纪末的瑞士,后在美国发展、并在日本得以发扬光大的数学智力拼图游戏。数独的玩法逻辑简单,数字排列方式千变万化。不少教育者认为数独是锻炼脑筋的好方法。数独游戏成功的原因除了它的趣味性和挑战性之外,更重要的原因其实是因为它很容易上手。玩这个游戏只需要认识19这九个数字,然后再需要一定的逻辑推理加上必要的耐心就可以了。

数独游戏的规则是:在一个9x9的大正方形中,每一行和每一列都必须填入19 的数字,不能重复也不能少;在每个由粗线隔开的3 x 3小九宫格(也被称为“区”)中,也必须填入19的数字,同样不能重复也不能少;每个数独游戏只有一个解答方案。一般而言,一条数独题会给出1/3左右的数字作为初始条件,剩下的2/3空白处由读者完成。简单的数独题目初始时会有更多的数字。

C语言模拟数独的人工解题思路,有利于学习C语言及相应的编程技巧,不仅可以找寻计算机程序与人思维方式的差异,而且可以尝试着把人的思维方式转化成相应的计算机程序,便于今后人工智能方面的研究。

 

二、数独解题思路

数独游戏上手简单,但是随着难度的加大将会充满挑战。数独的解题方法多种多样,归纳起来主要有三种方法:唯一法、排除法和尝试法。

唯一法指的是在任何一行、一列或一区中,如果仅有一个数字没有填上,那么这个数字一定是目前在这一行、这一列或是这一区里应该填上的那个数字。排除法指的是假如在某一行中的两个空格拥有相同的两个候选数字,虽然不能确定哪一个数字应该放在哪一个空格中,但至少可以确定,这一行中没有任何其他的空格可以放入这两个数字。这个原则同样适用于列和区。尝试法指的是首先选定一个候选数最少的空格,再选择其中较小的一个候选数字,假定这个候选数字就是最终的答案,然后根据往下判定其它空格,如果最终解决问题当然万事大吉;如果发现在某一相同的行、列或区中一定会出现相同的两个数字,那么可以断定前面的假设是错误的;这个时候,要重新选择另一个候选数字进行尝试,直到解题。

当然唯一法、排除法及尝试法还可以扩展,这些在用C语言实现时将做进一步探讨。从解题的顺序来看,优先使用唯一法。在唯一法无法实现解题的前提下,再使用排除法。一般入门级、中级、高级,甚至某些黄金级(骨灰级)的题目用这两种方法是可以解题的。如果在前两者循环使用后,仍然不能解决问题,再使用尝试法。高级或黄金级(骨灰级)的题目通常要用到尝试法,有些难题甚至要多次尝试,对许多空格都要尝试。如果尝试过多,人工解题就失去了太多的乐趣。通常对某一个空格使用尝试法之后,再结合唯一法、排除法可以顺利解题。

 

三、C语言程序

1唯一法

这里以2006年首届世界数独大赛决赛题目为例来说明用C语言模拟数独的人工解题思路。此题用C语言描述如下:

int a[x][x]={

0,0,0,7,5,0,0,0,0,

0,3,0,0,4,8,0,2,0,

1,0,0,0,0,0,0,0,6,

0,4,0,0,0,0,0,0,8,

7,9,0,0,0,0,0,3,1,

2,0,0,0,0,0,0,7,0,

5,0,0,0,0,0,0,0,7,

0,8,0,3,2,0,0,4,0,

0,0,0,0,6,9,0,0,0

              };

其中x90代表空格。这是一个二维数组,按C语言来定行列,如第1行的7其行列为[0][3]。人工解题首先考虑的是哪一个空格只有唯一解,由本题可见,a[4][4]只能填8,因为其行、列或区中已经有了除8以外其它1-98个数据;写入8之后,接下来可在a[6][4]写入1a[6][5]写入4a[6][3]写入8a[8][3]写入5a[7][5]写入7

人可以一眼看出象这样的唯一解,但计算机不行,必须用相应的程序来实现此功能。首先需要对行中的整数0进行计数,记录其相应位置。然后寻找每一行、每一列、每一区中缺少的整数。不提倡用随机数来生成数据,一来没有必要,二来用循环及判断很容易找到缺少的数据。最后找出每个空格可写入的整数(即候选数)与每个空格总共可写入几个整数(即个数)。找候选数及其个数的程序较难,以此为例略加说明:

    for (r=0; r<x; r++)

    for (h=0; h<rowcnt[r]; h++)             

    {

                n=r/3;        

                t=wei[r][h];

                m=t/3+3*n; 

        if(b[r][t]==0)

        {

            for (j=0; j<colcnt[t]; j++) 

            {

                for (i=0; i<rowcnt[r]; i++)  

                {      

if (roww[r][i]>0 && roww[r][i]==colw[t][j]) 

//寻找相同的整数

//首先是每行缺少的整数与列中的第1个数比较

//然后是列中的每行数据依次被比较

//再是wei的位置进行移动

//最后是换到下一行

                    {

                    aflag = 1;

                    break;  //跳出i

                    }

                    else

                        aflag =0;

                }//--end for i

            if (aflag ==1)

            {

                for (q=0; q<newcnt[m]; q++) 

                {

if (neww[m][q]==roww[r][i])

                    {                       xian[r][h][rowk]=roww[r][i];

                        rowk++;

                        break;//跳出q

                    }

                }          

            }  //end if (aflag ==1)

                aflag=0; 

            }   // end for j                   

        }//end if(b[r][t]==0)

    samecnt[r][h] = rowk;

     rowk = 0;

    }   // end for h

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089