poj 2676 sudoku ( 数独)----DFS
2012-03-07 19:20 java环境变量 阅读(292) 评论(0) 编辑 收藏 举报
Sudoku
Time Limit: 2000MS | Memory Limit: 65536K | |||
Total Submissions: 9664 | Accepted: 4786 | Special Judge |
Description
Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal
is to fill the empty cells with decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task.
Input
The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in
this line. If a cell is empty it is represented by 0.
Output
For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.
Sample Input
1 103000509 002109400 000704000 300502006 060000050 700803004 000401000 009205800 804000107
Sample Output
143628579 572139468 986754231 391542786 468917352 725863914 237481695 619275843 854396127
/* 只能说可能是poj的测试数据太诡异。。 我从第一个开始搜的代码 交的结果 Memory: 164 KB Time: 1422 MS Language: C++ Result: Accepted 然后看了下poj关于此题的Dicuss。。。看到说倒着搜可以缩时间。 结果是 16MS.... 无语了。 这道题我是直接DFS。 所以时间用了1422MS。 下面是倒着搜的代码。 */ //Memory: 164 KB Time: 16 MS //Language: C++ Result: Accepted #include<stdio.h> #include<string.h> const int MAX=9; int dfs(int m,int count); //DFS搜索 int judge(int x,int y,char t); //判断是否可以放数字t char gird[MAX][MAX],vir[MAX*MAX]; int tot; int main() { //freopen("1.txt","r",stdin); int n; int i,j; while(scanf("%d",&n)!=EOF) { while(n--) { tot=0; memset(vir,0,sizeof(vir)); for(i=0;i<MAX;i++) { scanf("%s",gird[i]); for(j=0;j<MAX;j++) if(gird[i][j]=='0') tot++; //统计需要填的格子数 } dfs(80,0); //倒着搜 效果很神奇。。。 printf("\n"); } } return 0; } int dfs(int m,int count) { int i,j; int x=m/MAX,y=m%MAX; if(count==tot) //如果全部格子都填满 并不冲突 打印结果 { for(i=0;i<MAX;i++) { for(j=0;j<MAX;j++) printf("%c",gird[i][j]); printf("\n"); } return 1; } if(gird[x][y]=='0'&&!vir[m]) //判断是否是空的格子 { for(i=1;i<10;i++) { if(judge(x,y,'0'+i)) //判断尝试的数字i 是否与已有的数冲突 { vir[m]=1; gird[x][y]='0'+i; if(!dfs(m-1,count+1)) //满足则 继续深搜 { vir[m]=0; //如果尝试失败 记得复原 gird[x][y]='0'; } else return 1; } } } else if(dfs(m-1,count)) return 1; //如果不是 则搜索下一个 return 0; } int judge(int x,int y,char t) { int i,j; for(i=0;i<MAX;i++) //判断行列是否冲突 if(gird[x][i]==t||gird[i][y]==t) return 0; int tempx=(x/3)*3,tempy=(y/3)*3; for(i=tempx;i<tempx+3;i++) //判段九个小格子是否冲突 for(j=tempy;j<tempy+3;j++) if(gird[i][j]==t) return 0; return 1; }