题意:给一个9*9的数独,其中已经填了一些数了,需要填上剩下的空,如有多解随意输出一解即可。
思路:由于这题初始给的数很多,所以直接dfs不用剪枝也可以过。数独需要每一行每一列,9个3*3的区域内不能有重复的数字。对于每一行每一列的判断很容易,关键在于子网格的判断。参考了大佬的思路,设子网格的编号为0-8,设一个小格(i,j)(0<i<9,0<j<9)的编号为k
则3*(i/3)+j/3==k;
这样就容易判断了。
bool row[10][10]//判断行
bool col[10][10]//判断列
bool g[10][10]//判断子网格
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; char s[10][10]; int a[10][10]; int dict[4][2] = {-1,0,0,1,1,0,0,-1}; bool row[10][10]; bool col[10][10]; bool g[10][10]; int flag; void dfs(int x,int y) { if(x==9) { flag = 1; return; } if(a[x][y]) { if(y==8) dfs(x+1,0); else dfs(x,y+1); } else { for(int i = 1; i <= 9; i++) { int k = 3*(x/3)+y/3; if(row[x][i]==0&&col[y][i]==0&&g[k][i]==0) { row[x][i] = 1; col[y][i] = 1; g[k][i] = 1; a[x][y] = i; if(y==8) dfs(x+1,0); else dfs(x,y+1); if(flag) return; else { row[x][i] = 0; col[y][i] = 0; g[k][i] = 0; a[x][y] = 0; } } } } } int main() { int T; cin >> T; while(T--) { memset(row,false,sizeof(row)); memset(col,false,sizeof(col)); memset(g,false,sizeof(g)); for(int i = 0; i < 9; i++) { for(int j = 0; j < 9; j++) { cin >> s[i][j]; a[i][j] = s[i][j]-'0'; if(a[i][j]) { int k = 3*(i/3)+j/3; row[i][a[i][j]] = true; col[j][a[i][j]] = true; g[k][a[i][j]] = true; } } } flag = 0; dfs(0,0); for(int i = 0; i < 9; i++) { for(int j = 0; j < 9; j++) { cout << a[i][j]; } cout<<endl; } } return 0; }