C语言中的数独问题(回溯)
2017-11-02 23:27
197 查看
描述:
数独游戏规则
在9阶方阵中,包含了81个小格(九列九行),其中又再分成九个小正方形(称为宫),每宫有九小格。
游戏刚开始时,盘面上有些小格已经填了数字(称为初盘),游戏者要在空白的小格中填入1到9的数字,
使得最后每行、每列、每宫都不出现重复的数字,而且每一个游戏都只有一个唯一的解答(称为终盘)。
输入:
一个9*9的矩阵,0表示该位置是空白。
输出:
一个9*9的矩阵,格式与输入类似。
输入样例:
900050060
020070100
300102040
703800529
000345000
516009403
050208006
007090010
030010004
输出样例:
971453268
428976135
365182947
743861529
892345671
516729483
154238796
687594312
239617854
1.这道题的输入很奇怪。如果一开始把数据输入到int型数组中,数组中就会有9个9位的数,而不是81个1位的数。所以只能把数据输入到字符型数组中,这样才能保证每次只读取一个数字。
2.用回溯法穷举二维数组时,不需要声明两个变量,只需要一个变量经过/和%运算就可以确定行和列。
3.在for循环后添加shudu[x][y]的必要。
和普通穷举不同,普通穷举时不需要考虑不同位置间数的关系;
和8皇后问题也不同,8皇后问题只需要考虑新加入的数和其左边其上边的数的关系;
数独问题中,每一个数和其前后左右的数都有关系。
所以一个位置在当前情况下取不到值时,应该在回溯前把该位置的值返回0,这样才不会影响其他数的取值,
相当于开始讨论一种新的情况。
如果不返回0,在讨论前面位置的其他情况时仍然会受这个位置的9的影响。
数独游戏规则
在9阶方阵中,包含了81个小格(九列九行),其中又再分成九个小正方形(称为宫),每宫有九小格。
游戏刚开始时,盘面上有些小格已经填了数字(称为初盘),游戏者要在空白的小格中填入1到9的数字,
使得最后每行、每列、每宫都不出现重复的数字,而且每一个游戏都只有一个唯一的解答(称为终盘)。
输入:
一个9*9的矩阵,0表示该位置是空白。
输出:
一个9*9的矩阵,格式与输入类似。
输入样例:
900050060
020070100
300102040
703800529
000345000
516009403
050208006
007090010
030010004
输出样例:
971453268
428976135
365182947
743861529
892345671
516729483
154238796
687594312
239617854
1.这道题的输入很奇怪。如果一开始把数据输入到int型数组中,数组中就会有9个9位的数,而不是81个1位的数。所以只能把数据输入到字符型数组中,这样才能保证每次只读取一个数字。
2.用回溯法穷举二维数组时,不需要声明两个变量,只需要一个变量经过/和%运算就可以确定行和列。
3.在for循环后添加shudu[x][y]的必要。
和普通穷举不同,普通穷举时不需要考虑不同位置间数的关系;
和8皇后问题也不同,8皇后问题只需要考虑新加入的数和其左边其上边的数的关系;
数独问题中,每一个数和其前后左右的数都有关系。
所以一个位置在当前情况下取不到值时,应该在回溯前把该位置的值返回0,这样才不会影响其他数的取值,
相当于开始讨论一种新的情况。
如果不返回0,在讨论前面位置的其他情况时仍然会受这个位置的9的影响。
#include<stdio.h> int shudu[9][9]; char temp[9][10]; void search(int m); void output(); int check(int m); int main() { for(int i=0;i<9;i++) { for(int j=0;j<=9;j++) { scanf("%c",&temp[i][j]);//每次只读取一个数字 if(temp[i][j]!='\n') { shudu[i][j]=temp[i][j]-'0'; } } } search(0); return 0; } void search(int m) { if(m>=1&&m<=81) { if(check(m-1)==0) return; } if(m==81) { output(); } if(m>=0&&m<=80) { int x=m/9; int y=m%9; //将m转化为二维数组的形式 if(shudu[x][y]!=0)//不再改变输入时确定的数(1-9) { search(m+1); } if(shudu[x][y]==0)//讨论空位(0)的可能取值 { for(int i=1;i<=9;i++) { shudu[x][y]=i; search(m+1); } shudu[x][y]=0; /*和普通穷举不同,普通穷举时不需要考虑不同位置间数的关系; 和8皇后问题也不同,8皇后问题只需要考虑新加入的数和其左边其上边的数的关系; 数独问题中,每一个数和其前后左右的数都有关系。 所以一个位置在当前情况下取不到值时,应该在回溯前把该位置的值返回0,这样才不会影响其他数的取值, 相当于开始讨论一种新的情况。 如果不返回0,在讨论前面位置的其他情况时仍然会受这个位置的9的影响。*/ } } } int check(int n) { int x=n/9; int y=n%9; int i,j; for(i=0;i<=8;i++)//检查每列中不出现重复数字 { if(i!=x&&shudu[i][y]==shudu[x][y]) return 0; } for(j=0;j<=8;j++)//检查每行中不出现重复数字 { if(j!=y&&shudu[x][j]==shudu[x][y]) return 0; } int l=(x/3)*3,c=(y/3)*3; for(i=l;i<=l+2;i++) { for(j=c;j<=c+2;j++) { if((i!=x||j!=y)&&shudu[i][j]==shudu[x][y]) return 0;//检查小九宫格中是否有重复数字 } } return 1; } void output()//输出 { for(int i=0;i<9;i++) { for(int j=0;j<9;j++) { printf("%d",shudu[i][j]); } printf("\n"); } }
相关文章推荐
- C语言 递归(回溯) 解决数独问题
- C语言 递归(回溯) 解决数独问题
- 数独C语言编程-正推与回溯
- hdu Problem-1426数独问题(dfs+回溯+枚举)
- c语言:回溯解数独程序
- Java回溯算法解数独问题
- 回溯法-旅行售货员问题(C语言)
- C语言及程序设计进阶例程-26 回溯溯法问题求解
- 全排列问题(c语言实现)回溯法 排列树
- 回溯法解数独问题
- 回溯算法解数独问题(java版)
- c语言三阶幻方问题(回溯)
- C语言中的素数环问题(回溯)//函数exit的使用
- 数独问题(DFS回溯)
- 算法之6-回溯法解数独问题
- C语言回溯法装载问题
- c语言编程:优化回溯解数独程序
- C语言用回溯解决八皇后问题
- 数独问题(DFS回溯)
- 迷宫问题--非递归回溯 C语言实现