我要用C语言写一个解数独题目的程序,从我刚开始接触数独的时候,我就这样告诉自己。记得那是暑假的一天。在家闲来无事,就翻开了以前买的一本
《数独》。从看前面的例题开始,然后自己解第一个题,之后便一发不可收拾。彻彻底底迷上了这9个数字的各种组合变幻。刚好那时有在自学点C语言(说是学习,其实也就是买了几本书看看,上机的时间很少,没条件啊),就想着如果能用C语言写一个解数独的程序那多好啊!那样在同学面前说了N久的“学”编程也能稍稍兑点现了撒。顺便再吹吹牛,得意得意。可是那是自己也就会写
HELLO WORLD
啊(虽然现在也差不多,嘿嘿)。就一直搁浅了这个计划,只是自己天天用笔算,有时候一两个小时都解不出来,但我还是坚持,我喜欢解出题目的成就感,大家是不是都有这样的感觉呢?
直到这个暑假,家里给买了电脑(不容易啊,我盼了N久哩)。就慢慢想着怎么解题了。不过,你知道的。我啥也不会啊,算法,数据结构,都晕着呢。不过我心里还是有一个朦胧的想法,并且相信自己能实现这个想法。关键是跨出那一步。有些事看起来很难,其实只要能跨出第一步,就是成功的一半了。
我跨出了那一步!
我想实现的第一个功能就是数独第一页交给我的解题方法:夹逼法(是不是呢?这个名字书上好像没有明确的定义)。就是3行中有两行都有数字A,然后然后找出没有数字A的那一行再根据列填出数字A.(说的不清楚,呜呜)
还有当我发现一个格子有两个待选的数而现在又不能确定的时候,可以把这两个数字和位置记录下来,等这两个数字其中一个确定,那么另一个也可以确定了。
还有当一行或一列或哪个小九宫格有8个数字的时候,最后一个数字也就可以确定下来了。
还有用夹逼法遍历完9行之后,再遍历9列。方法是把数独翻转90°就可以了。因为这样只要用一个函数来解就可以了。
我只完成了上面这几个功能模块,还好,数独初级的题目能够“秒杀”。
刚看到屏幕输出“解题完成”这几个字的时候,真兴奋,开心。每天熬到半夜总算有些许回报了。
上面的是题目,下面的解好的题目。不过被顺时针旋转了一下还没转回来的。呵呵。
能帮我写个函数转回来吗?~_~
虽然我算法和数据结构基础都很差。但我还是能依靠自己的小小想象力解决它。
关键是踏出第一步。后续把的程序整理整理。多完成几个模块,它的下一个目标,
“秒杀”中级数独。不过在这之前,我认为我极有必要去好好学点算法和数据结构的知识,
还有多上机敲代码,好记性还不如烂笔头呢.呵呵,我相信我能完成!!!
关于解数独,我觉得关键在于数据。计算机的强项就是操控数据撒
数据的设计
主数组用于保存整个数组的信息:SoDu[10][10] (为计算方便,第一个元素不用,下标刚好可以对应9)
整个题目已经完成的数字数:ach_Number; (为81时就解完题目啦)
保存每个数字填入题目的个数:ach_Times[10] (第一个元素不使用,下标第i个元素值代表数字i已填入多少个。
每行每列每个小九宫格的数据信息:
a) ach_Line [10]; //表示每行已经完成的数字数
b) ach_Row [10]; //没列已经完成的数字数
c) ach_Xiao [10]; //表示每个小九宫格已经完成的数字数
从九行的角度看整个数组题目: ach_LineNum[10][10]; //ach_LineNum[i][j] 若值为1表示第i行的数字 j
已经填入。以此类推,从列的角度来看是 ach_RowNum[10][10];
从每个小九宫格的角度来看是 ach_XiaoNum[10][10].
刚开始我是把这些数据声明成全局变量,但是这不利于函数的抽象,因为需要在多个函数中操作这些变量。所以我把它们并入一个结构体变量,那么只要向函数传递一个指针就可以实现这些数据的操作了。好的,整理一下就是:
struct SoduData{
int SoDu[10][10];
int ach_Times[10];
int ach_Line[10], ach_Row[10] , ach_Xiao[10];
int ach_LineNum[10][10], ach_RowNum[10][10],
ach_XiaoNum[10][10];
int ach_Number;
};
英语不咋地,声明的数据名字奇奇怪怪的。好吧,英语也是重点学习的对象
不过22号有自学考试,我地格填呐。3科全挂都有希望。我都没看的。
临时抱佛脚吧,希望不要挂的太惨。回来之后安心写的程序。C语言!!!
My Name Is 影霖魂