求解: 数独求解器

数独求解-数独的一般解法 _星空生活网
你现在浏览的是: & > &
__7_____!
__8___67_!
_7____4__!
6___1_____!
___3_7___!
求大手给解一下,最好带过程,简化过程就行!
____2___1!
843______!
_5_____8_!
_____8__4
有唯一解 是窗口数独即除每行每列1-9不重复外,四个小3x3窗口1-9不重复。3 247 5 619 85 189 4 367 29 762 8 145 36 354 1 982 72 813 6 754 9 4 978 2 536 18 436 9 271 57 521 3 498 61 695 7 823 4
有唯一解 是窗口数独即除每行每列1-9不重复外,四个小3x3窗口1-9不重复。3 247 5 619 85 189 4 367 29 762 8 145 36 354 1 982 72 813 6 754 9 4 978 2 536 18 436 9 271 57 521 3 498 61 695 7 823 4
就是说这道题有无数的解,你看看是否有错,几乎做不下去,用候选数法精简到下面这个程度【以空格为单元格分开标志】:123459
到后面还是不好做下去,只好用试探法,关键的是:
这一行,你的空格数量应该多了一个,也许我判断出错会因这一行如果我转换的错了,就不用看后面了,算我白忙活如果没错,那你这道数独题也太多解了,到后面还出现了两组对称的解,试探了至少8个数字首先,做这个题没多大意思,浪费时间,给你一个我乱填但又符合此题要求的一组解吧,你这个出题方式有问题,那些空格让人不能直接看出来你到底有多少空格,你最好把空格打成0或者逗号星号什么的,这样人家一眼就能看出来这题目,帮你用软件转换了下,原题如下
什么东西解啤酒 :
在日常生活中,一旦遇到有人喝醉酒时,不妨可以参考以下一些方法进行解酒,这些食疗方法都是我国民间通过大...
月既不解饮,影徒随我身 “解”是什么意思? :
出自李白的《月下独酌》 解: 助动词。能,会,得 http://www.zdic.net/zd/zi...
lol净化可以解哪些技能 :
净化是lol中召唤师技能之一,可以清除自己身上的状态。 1、定身限制状态。包括眩晕(蜘蛛的e等),禁...
俗人多泛酒,谁解助茶香中的“解”是什么意思? :
《九日与陆处士羽饮茶》 九日山僧院, 东篱菊也黄。 俗人多泛酒, 谁解助茶香。 &俗人都泛酒,谁解助...
解的姓氏读音 :
解,xie,四声.
英雄联盟视角锁定了,怎么解都解不了 :
右下角点眼睛就解锁了,不行继续追问
如何能解红酒? :
事前办法: 最好的解酒方法是事前防范,先将具体方法提供如下: a、吃ru21安体普复合片,是目前全球...
怎么解宿醉? :
所谓宿醉,是指喝酒过量,造成第二天早上头痛、胃部不适等症状。这是因为大量饮酒后,肝细胞无法将有害物质...
只有零解和有非零解是什么意思?6766 :
齐次线性方程组只有零解:说明只有唯一解且唯一解为零(因为零解必为其次线性方程组的解),即A的秩r(A...
股市什么叫解票 :
1、解票既是解析、分析股票的意思。 2、股票市场的分析方法主要有如下三种:基本分析、技术分析、演化分...
朋友,现在我们要向你说说这个迫不及待、需要解决的问题——信耶稣得永生。“你若口里认耶稣为主,心里信神叫祂从死里复活,就必得救。——罗马书10:9”
我们曾经被人说是“迷信”、“唯心”,但我们不承认我们是迷信、唯心的。不信有神的人倒是迷信和唯心的呢!没有的、假的,我们硬说是有、是真,这就是迷信与唯心。明明是有神,但闭起眼睛说“没有”,这不是迷信与唯心又是什么呢?也许你会说:“你这个人太奇怪了,把没有看见的神,说成‘明明有’,还说别人迷信与唯心!”请注意,不信有神的人往往用“看不见”来欺哄自己。试想,看不见的东西有多少?最高的山,最深的海,最北的北极和最南的南极,地球的核心以及千千万万的事物,我们都没有见过,为什么我们信它们是存在的呢?没有看见过的东西,我们怀疑它的存在,这倒不太奇怪,最奇怪的是我们去否定它!
如果你再没有机会遇见信耶稣的人,或者没有机会到福音堂,就请你回忆以上所说的这几节经文,决心相信。你什么时候相信,什么时候就得救;你什么时候离开世界,什么时候就到天家。这是一个最简单的方法,这是一个最大的福气。你不用一分钱来赎你的罪,只要你用信心,接受已经作成的救赎工作;你不用靠立功行善来获得永生,在你真心相信后,才谈得上善行。在你真心接受救恩后,每天祈祷,生命会有大改变,心里充满了喜乐平安,因为你有了新生命,而且你的生命是有保障的——永不灭亡!这是恩典,请你现在就立即接受耶稣作你个人的救主!如果你现在不信,以后遇到了什么危险的时候,请你回忆我对你所说过的话,立即祈祷神,接受耶稣,还是可以的。但请你不要等到危难的时候才信,恐怕你的生命不留情,至使你来不及信,那你就后悔莫及,结果永远受苦!请你保留这本小册子,经常翻阅,直到你接受救恩。再见!
你可能感兴趣的内容?你是如何一步步成为数独高手的? - 知乎95被浏览16058分享邀请回答3014 条评论分享收藏感谢收起12 条评论分享收藏感谢收起查看更多回答数独求解_数独吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:56,715贴子:
数独求解收藏
数独,亚马逊网上书城,好书不间断!全场自营图书满59元免运费,自在购书,不用凑单哦!买数独,就上Z.CN!正版图书,天天低价特惠,让您挚爱阅读!
有没有人知道
只看每行每列每区
先自学吧主解题方法,,自己做,做到做不下去了,再发。如果你能都学会,这题,不在话下
新手,不知道答案是不是唯一。废了劲了就这个
不过,第一个数好像抄错了
登录百度帐号推荐应用在线破解数独博客访问: 2605671
博文数量: 167
博客积分: 3918
博客等级: 少校
技术积分: 8363
注册时间:
个人微薄: /manuscola
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
& & 我毕业那年,在公司参加了TDD的培训,其中一个讲师讲的一个例子是数独,当时我们通过较长时间的培训解决了这个很难的问题。去年重装系统,没做好备份,当时的代码都不见了,我只好时隔1年3个月后,再次写下数独的代码。
& & 在当时的情况下,TDD(测试驱动开发)的思想是给我很大的帮助的,写程序要写测试代码,是当时学会的思想。现在,随着有些咨询培训机构将TDD神话,我觉得有点过了。一个合格的程序员需要测试自己的code,但是驱动一词,有点过分了。我觉得,测试代码会让你成为一个合格的程序员,但是不会帮助你成为一个优秀的程序员。要想变成一个优秀的code,需要大量的阅读优秀的代码,学习别人的代码,大量的练习写代码。在一次次痛苦中成长。当你透彻的理解算法,当你站的高度比较高的时候,自然能够写出质量高而又优美的code。当然我还远远不够,我充其量就是一个普通的coder,但是我决心学习前辈的分享,潜行修行,成为一个好coder。
& & 我找到了大师Peter Norvig的文章Solving Every Sudoku Puzzle,大师就是大师,此文一出基本上解决了数独相关的所有问题。内容十分的翔实,python代码写的也很漂亮,给出了分析。我基本没有指望讲的比Peter Norvig更清楚了。对原理比较感兴趣的,可以去看这篇文章。
& & &A1 A2 A3| A4 A5 A6| A7 A8 A9 4 . . |. . . |8 . 5
4 1 7 |3 6 9 |8 2 5
&&&&&B1 B2 B3| B4 B5 B6| B7 B8 B9 . 3 . |. . . |. . . 6 3 2 |1 5 8 |9 4 7
&&&&&C1 C2 C3| C4 C5 C6| C7 C8 C9 . . . |7 . . |. . . 9 5 8 |7 2 4 |3 1 6
&&&&---------+---------+---------
------+------+------
------+------+------
&&&&&D1 D2 D3| D4 D5 D6| D7 D8 D9 . 2 . |. . . |. 6 . 8 2 5 |4 3 7 |1 6 9
&&&&&E1 E2 E3| E4 E5 E6| E7 E8 E9 . . . |. 8 . |4 . . 7 9 1 |5 8 6 |4 3 2
&&&&&F1 F2 F3| F4 F5 F6| F7 F8 F9 . . . |. 1 . |. . . 3 4 6 |9 1 2 |7 5 8
&&&&---------+---------+---------
------+------+------
------+------+------
&&&&&G1 G2 G3| G4 G5 G6| G7 G8 G9 . . . |6 . 3 |. 7 . 2 8 9 |6 4 3 |5 7 1
&&&&&H1 H2 H3| H4 H5 H6| H7 H8 H9
5 . . |2 . . |. . . 5 7 3 |2 9 1 |6 8 4
&&&&&I1 I2 I3| I4 I5 I6| I7 I8 I9
1 . 4 |. . . |. . . 1 6 4 |8 7 5 |2 9 3
& & 数独是9X9的结构,每个位置存放1~9之间的数字,9个行,9个列,加上9个3*3的block组成了27个group,要求。group内的数字不准重复出现,必须1~9各出现一次。题目会给出初始状态,如中间的图。
& & 任何一个数字同时属于3个group,所在的列,所在的行,及所在的block。如下图的C2。
& & 为什么有关注任何一个cell所属的group? 一个cell的值value一旦确定,这个group里面其他的cell就不许出现这个value,group里面的其他cell的可能性就会减少。如果可能性减少到1个,那么就是确定了这个cell的值。
& &另一个需要关注的概念是伙伴,peer,在3个group的每个元素(除了自身),都是自己的伙伴,伙伴和自己息息相关,比如C2 = 4 ,那么C2 的20个伙伴都不能等于4。CELL 值的确定会减少伙伴的不确定性。
& & 初始化的时候9*9=81个cell,每个cell的可能性都是1~9,9种可能,一旦给某个cell 赋值,assign,本质是消灭了本cell的其他8种可能性。 任何一个cell一个可能行的减少,都会带来连锁反应:
& & 1 该cell 可能性已经减少到了0, 无解
& & 2 该cell的可能性已经减少的了1 ,这就不是可能性了,这就是确定性了。cell的确定性就减少了cell的伙伴的不确定性,cell的伙伴都不能等于cell的值。
& & 3 &cell 不能等于value,对于group里面的9个值,总有一个要等于value。 如果group 可能等于value的cell个数降到了0个,那么无解。如果降到了1个,那么可能等于value的那个cell就确定了。又引发了连锁反应。。。
& & 对于比较简单的数独,约束传播可能直接带来最后的结果,但是也有比较复杂的数独题目,初始值 约束传播不能得到最终的结果,某些个CELL,可能还有多个可能性,如下图,我们可以看到,有些CELL 已经确定了值,但是有些CELL,还是存在多种可能性。这就需要第二个策略 搜索.
& & 搜索是指,已知帮我们走到了尽头,剩下的要靠我们试错,我们选择一个可能性比较少的CELL,
分别碰碰运气,如果CELL[2][2] 的可能性只有3种(1,4,7),我们就试试,我们假定CELL[2][2]=1,这会带来约束传播的风暴,随着这个值的确定(人为指定),我们可能得到最终的结论,如果还是没有最终解决,我们再次递归search,如果我们失败了CELL[2][2] =1 会造成数独无解,那么我们回退回来,重新试试CELL[2][2] = 4....
& & &原理部分就是这写了,代码写的不太好,今天写代码不在状态,总是出现低级错误,耗费了不少时间。
#include&stdio.h&
#include&stdlib.h&
#include&assert.h&
#define ELEMENT_PER_LINE (9)
#define ELEMENT_NUM ((ELEMENT_PER_LINE)*(ELEMENT_PER_LINE))
#define BLOCK_WIDTH (3)
#define MAX_PEER_NUM (20)
#define MAX_UNIT_MEMBER (9)
typedef struct sudoku_elm{
unsigned int peer[MAX_PEER_NUM] ;
unsigned int peer_
unsigned int unit[3][MAX_UNIT_MEMBER];
unsigned int top_x;
unsigned int top_y;
unsigned int top_b;
unsigned short possibility[9];
static int malloc_count = 0;
static int cpy_cnt = 0;
inline init_possibility(struct sudoku_elm* result,int index)
int k = 0;
for(k = 0 ; k & 9;k++)
result[index].possibility[k]=1;
inline count_possibility(struct sudoku_elm* result ,int index)
int k = 0;
int count = 0;
for(k = 0 ;k & 9; k++)
if(result[index].possibility[k] == 1)
int get_nth_possibility(struct sudoku_elm* result,int index,int n)
int k = 0;
int j = -1;
for(k = 0 ; k&9;k++)
if(result[index].possibility[k] == 1)
if(j == n)
return k+1;
int get_first_possibility(struct sudoku_elm* result ,int index)
return get_nth_possibility(result,index,0);
int is_have_possibility(struct sudoku_elm* result,int index,int value)
return (result[index].possibility[value-1] == 1);
int clear_possibility(struct sudoku_elm* result,int index,int value)
result[index].possibility[value-1] = 0;
init_sudoku(struct sudoku_elm* result)
assert(result != NULL);
memset(result,0,sizeof(struct sudoku_elm)*ELEMENT_NUM);
for(i = 0 ; i&ELEMENT_NUM;i++)
init_possibility(result,i);
int x = i/(ELEMENT_PER_LINE);
int y = i%ELEMENT_PER_LINE;
for(j = 0 ; j&ELEMENT_NUM;j++)
int cur_x= j/ELEMENT_PER_LINE;
int cur_y= j%ELEMENT_PER_LINE;
if(cur_x == x)
result[i].unit[0][result[i].top_x++] =
if(cur_y == y)
result[i].unit[1][result[i].top_y++] =
if(cur_x/3 == x/3 &&
cur_y/3 == y/3)
result[i].unit[2][result[i].top_b++] =
int k = 0;
int m = 0;
for(m = 0; m&2;m++)
for(k = 0;k&ELEMENT_PER_LINE;k++)
if(result[i].unit[m][k] != i)
result[i].peer[result[i].peer_top++] = result[i].unit[m][k];
for(m = 0 ; m & BLOCK_WIDTH*BLOCK_WIDTH;m++)
if(result[i].unit[2][m]/ELEMENT_PER_LINE != x &&
result[i].unit[2][m]%ELEMENT_PER_LINE != y)
result[i].peer[result[i].peer_top++] = result[i].unit[2][m];
for(i = 0 ; i &ELEMENT_NUM; i++ )
assert(result[i].top_x == 9 &&
result[i].top_y == 9 &&
result[i].top_b == 9 &&
result[i].peer_top == 20);
int eliminate(struct sudoku_elm* result,int index,int value)
if(is_have_possibility(result,index,value)== 0 )
clear_possibility(result,index,value);
if(count_possibility(result,index) == 0)
return -1;//
int ret = 0;
if(count_possibility(result,index) == 1)
data = get_first_possibility(result,index);
for(i = 0 ; i & MAX_PEER_NUM; i++)
int peer = result[index].peer[i];
ret = eliminate(result,peer,data);
if(ret != 0)
return -2;
int cur_unit = 0;
int d_place[MAX_UNIT_MEMBER];
for(cur_unit = 0; cur_unit & 3;cur_unit++)
memset(d_place,0,sizeof(int)*MAX_UNIT_MEMBER);
int j = 0;
for(i = 0 ; i&MAX_UNIT_MEMBER;i++)
int unit = result[index].unit[cur_unit][i];
if (is_have_possibility(result,unit,value))
d_place[j++] =
if(j == 0)
return -3;
else if(j == 1)
ret = assign(result,d_place[0],value);
return -4;
int assign(struct sudoku_elm* result ,int index,int value)
if(!(value &= 1 && value &= 9 ))
return -1;
int i = 0;
int failed = 0;
for(i = 1 ; i &= 9 ; i++)
if(i == value)
ret = eliminate(result,index,i);
failed = 1;
if(failed)
return -2;
int parse_input(sudoku_elm* result,char* buf)
int failed = 0;
for(i = 0 ; i& ELEMENT_NUM; i++)
if(buf[i] &'0' && buf[i] &='9')
d = buf[i] - '0';
ret = assign(result,i,d);
if(ret & 0 )
failed = 1;
if(failed)
return -1;
int is_solved(struct sudoku_elm* result)
for(i = 0; i & ELEMENT_NUM;i++)
if(count_possibility(result,i) != 1)
int search(struct sudoku_elm* result)
if(is_solved(result) == 1)
int i = 0;
int idx = 0;
int min_count=10;
for(i = 0 ; i&ELEMENT_NUM;i++)
int count = count_possibility(result,i);
if(count & min_count && count & 1)
min_count =
struct sudoku_elm* result_cpy = NULL;
int success = 0;
for(i = 0 ; i&min_i++)
result_cpy = malloc(sizeof(struct sudoku_elm)*ELEMENT_NUM);
if(result_cpy == NULL)
fprintf(stderr,"can not malloc for try\n");
return -1;
malloc_count++;
memcpy(result_cpy,result,sizeof(sudoku_elm)*ELEMENT_NUM);
int value = get_nth_possibility(result_cpy,idx,i);
int ret = assign(result_cpy,idx,value);
if(ret == 0)
ret = search(result_cpy);
if(ret == 0)
success = 1;
free(result_cpy);
result_cpy = NULL;
free(result_cpy);
result_cpy = NULL;
if(success == 1)
memcpy(result,result_cpy,sizeof(sudoku_elm)*ELEMENT_NUM);
free(result_cpy);
cpy_cnt++;
return -1;
int display(struct sudoku_elm* result)
int max_count = 0;
for(i = 0 ; i & ELEMENT_NUM;i++)
count = count_possibility(result,i);
if(count & max_count)
max_count =
int width = max_count + 1;
fprintf(stdout,"------------------------------------------------------------------------------------------\n");
for (i = 0 ; i & ELEMENT_PER_LINE;i++)
for(j = 0 ; j& ELEMENT_PER_LINE;j++)
int k = count_possibility(result,i*9+j);
for(m = 0; m &m++)
fprintf(stdout,"%d",get_nth_possibility(result,i*9+j,m));
for(;m&m++)
fprintf(stdout," ");
fprintf(stdout,"\n");
fprintf(stdout,"malloc time (%d)\t cpy_cnt(%d)\n",malloc_count,cpy_cnt);
int sudoku(char* buf)
int ret = 0;
struct sudoku_elm* result = malloc(ELEMENT_PER_LINE*ELEMENT_PER_LINE*sizeof(struct sudoku_elm));
if(result == NULL)
fprintf(stderr,"malloc for sudoku failed\n");
init_sudoku(result);
ret= parse_input(result,buf);
fprintf(stderr,"parse failed\n");
display(result);
if( is_solved(result)== 1)
display(result);
ret = search(result);
if(ret != 0 )
fprintf(stderr,"search failed\n");
display(result);
if(result)
free(result);
int main()
char buf[128]=".....6....59.....82....8....45........3........6..3.54...325..6..................";
int ret = sudoku(buf);
if(ret != 0)
fprintf(stderr,"failed\n");
&&& 这个程序写的不好,不够简洁,好歹有个C 版本的数独程序了。呵呵,欢迎大家拍砖,或者写更好的代码。
参考文献:
1 Peter Norvig的博客 & &
阅读(4660) | 评论(1) | 转发(3) |
相关热门文章
给主人留下些什么吧!~~
现在难得有像兄弟这样对算法研究比较透彻的人了,赞一个。。。PS:反正我还没看懂,哈哈~~~空了再研究研究
请登录后评论。}

我要回帖

更多关于 用python求解多解数独 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信