数独1--暴力回溯法(时间超)
Posted 范仁义
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数独1--暴力回溯法(时间超)相关的知识,希望对你有一定的参考价值。
数独1--暴力回溯法(时间超)
一、心得
可用暴力搜索法(找唯一数单元格)和Dancing Links算法求解
先回顾之前的三篇文章
“算法实践——数独的基本解法”,介绍求解数独的基本的暴力搜索法
“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”,网友huangfeidian介绍的求解数独的舞蹈链(Dancing Links)算法,这篇文章是介绍舞蹈链(Dancing Links)算法的。
“算法实践——舞蹈链(Dancing Links)算法求解数独”,该文介绍了用舞蹈链(Dancing Links)算法求解数独,并给出了暴力破解法和舞蹈链(Dancing Links)算法之间的时间和空间占用效率的对比。
二、题目及分析
三、代码
时间超,未解决
1 /* 2 0 0 0 5 0 0 0 0 7 3 4 8 0 0 0 6 3 2 0 4 0 0 9 4 0 0 0 0 8 5 5 0 0 3 0 7 0 0 0 6 8 0 7 0 9 4 1 5 2 7 2 9 6 8 1 0 0 0 4 8 3 5 2 7 4 9 8 1 6 9 7 4 0 1 6 3 2 9 0 10 0 6 1 0 5 0 0 0 3 11 算法: 12 有点像八皇后问题 13 每一列至少都有一个 14 每一行至少有一个 15 每一个3*3小方框里面至少有一个 16 17 总过有9列,c[i][j]==1表示第i列的数字j已经有了 18 总过有9行,r[i][j]==1表示第i行的数字j已经有了 19 总过有9行,q[i][j]==1表示第k(从上到小,从左到右)个3*3的框数字j已经有了 20 21 只能摆那些没有被数字占了的位置 22 23 优化1:1-9每个数字只能出现9次 24 numTimes[i]表示数字i出现的次数 25 26 27 */ 28 29 #include <iostream> 30 #include <cstring> 31 using namespace std; 32 int c[10][10],r[10][10],q[10][10]; 33 int num[10][10]; 34 int numTimes[10]; 35 int step=0; 36 37 void readDate(){ 38 for(int i=1;i<=9;i++){ 39 for(int j=1;j<=9;j++){ 40 int x; 41 cin>>x; 42 if(x){ 43 step++; 44 numTimes[x]++; 45 num[i][j]=x; 46 r[i][x]=1; 47 c[j][x]=1; 48 //找到行列对应的小方框 49 int m=(i-1)/3*3; 50 int n=(j-1)/3; 51 int t=m+n+1; 52 q[t][x]=1; 53 } 54 55 } 56 } 57 } 58 59 void printData(int a[10][10]){ 60 for(int i=1;i<=9;i++){ 61 for(int j=1;j<=9;j++){ 62 printf("%3d",a[i][j]); 63 } 64 cout<<endl; 65 } 66 } 67 68 void search(int step){ 69 if(step==82) { 70 cout<<"--------------------------------------------------"<<endl; 71 printData(num); 72 } 73 else{ 74 for(int n=1;n<=9;n++){//填1-9这9个数 75 if(numTimes[n]==9) continue; 76 for(int i=1;i<=9;i++){ 77 for(int j=1;j<=9;j++){//i,j表示填num[i][j]位置的数 78 int m1=(i-1)/3*3; 79 int n1=(j-1)/3; 80 int t=m1+n1+1;//找i,j位置对应的方块 81 if(!num[i][j]&&!r[i][n]&&!c[j][n]&&!q[t][n]){ 82 num[i][j]=n; 83 numTimes[n]++; 84 r[i][n]=1,c[j][n]=1,q[t][n]=1; 85 search(step+1); 86 //回溯 87 num[i][j]=0; 88 numTimes[n]--; 89 r[i][n]=0,c[j][n]=0,q[t][n]=0; 90 } 91 } 92 } 93 } 94 } 95 } 96 97 int main(){ 98 freopen("shudu.txt","r",stdin); 99 readDate(); 100 printData(num); 101 cout<<"--------------------------------------------------"<<endl; 102 printData(r); 103 cout<<"--------------------------------------------------"<<endl; 104 printData(c); 105 cout<<"--------------------------------------------------"<<endl; 106 printData(q); 107 cout<<"--------------------------------------------------"<<endl; 108 for(int i=1;i<=9;i++){ 109 cout<<numTimes[i]<<endl; 110 } 111 cout<<step<<endl; 112 search(step+1); 113 cout<<"--------------------------------------------------"<<endl; 114 115 }
以上是关于数独1--暴力回溯法(时间超)的主要内容,如果未能解决你的问题,请参考以下文章