http://poj.org/problem?id=2676
题意 : 这个是我最喜欢玩的数独了,就是一个9乘9的宫格,填上1到9九个数字,每行每列每个宫格之内不能有重复的数字,给出的九宫格中,0是待填的数字,其他数字是已经填好的,若是无法按要求填出来,就输出原来的九宫格;
思路 : DFS,深搜递归一下,设三个标记数组,标记一下每行的,每列的,每个宫格的,如果这个数字出现了,就标记了就行,我代码里写的是标记数组row[ i ][ j ],代表的是第 i 行的 j 已经出现了,col[ i ][ j ]代表的是第 i 行的 j 数组存在,map[ i ][ j ]宫格 i 的 j 这个数字存在,而宫格的话大家可以自己想一下,如果一个位置的行和列是x,y,那么他所在的九宫格就应该是3*((x-1)/3)+(y-1)/3+1,但如果你往里输入的九宫格下标是从0开始的话,这个就要变成x/3*3+y/3,我也试过,但是从0开始存一直都是错的,后来就改为从一开始存了
#include<cstring> #include<cstdio> #include<iostream> using namespace std; int row[10][10],col[10][10],map[10][10];//行列宫格的标记数组 int Sudoku[10][10]; int flag ;//标记变量 int DFS(int x,int y) { if(x == 10) { for(int i = 1 ; i <= 9 ; i++) { for(int j = 1 ; j <= 9 ; j++) printf("%d",Sudoku[i][j]); printf("\n"); } return 1; } flag = 0 ; if(Sudoku[x][y])//该位置原本是有数字的 { if(y == 9) flag = DFS(x+1,1); else flag = DFS(x,y+1); if(flag) return 1; else return 0; } else { for(int i = 1 ; i <= 9; i++) if(!row[x][i] && !col[y][i] && !map[3*((x-1)/3)+(y-1)/3+1][i])//如果行列宫格都没有这个数字 { Sudoku[x][y] = i;//就填上这个数字,然后下边的行列宫格都标记为已填此数字 row[x][i]= 1; col[y][i]= 1; map[3*((x-1)/3)+(y-1)/3+1][i] = 1; if(y == 9) flag=DFS(x+1,1); else flag=DFS(x,y+1); if(!flag)//如果没找到合适的,就全部返回原值 { Sudoku[x][y]=0; row[x][i] = 0; col[y][i]= 0; map[3*((x-1)/3)+(y-1)/3+1][i]=0; } else return 1; } } return 0; } void Init() { memset(row,0,sizeof(row)); memset(col,0,sizeof(col)); memset(map,0,sizeof(map)); } int main() { int i,j,n; scanf("%d",&n); for(int s = 0 ; s < n ; s++) { Init(); for(i = 1 ; i <= 9 ; i++) for(j = 1 ; j <= 9 ; j++) { scanf("%1d",&Sudoku[i][j]); if(Sudoku[i][j]) { row[i][Sudoku[i][j]] = 1; col[j][Sudoku[i][j]] = 1; map[3*((i-1)/3)+(j-1)/3+1][Sudoku[i][j]] = 1 ; } } DFS(1,1); } return 0; }