1. 程式人生 > 其它 >深度優先搜尋(DFS)解數獨問題

深度優先搜尋(DFS)解數獨問題

 

#include<bits/stdc++.h>
using namespace std;
int a[10][10];
bool h[10][10],l[10][10],g[10][10],flag;
int pre[9][9] = {    //可以通過行列判斷是在哪個9宮格
1,1,1,2,2,2,3,3,3,
1,1,1,2,2,2,3,3,3,
1,1,1,2,2,2,3,3,3,
4,4,4,5,5,5,6,6,6,
4,4,4,5,5,5,6,6,6,
4,4,4,5,5,5,6,6,6,
7,7,7,8,8,8,9,9,9,
7,7,7,8,8,8,9,9,9,
7,7,7,8,8,8,9,9,9
};
void dfs(int k){
if(flag) return ;
if(k>80){  //如果走到第81,則說明已經填完了數獨,則輸出當前答案即可
for(int i = 0 ; i < 9 ; i++){
for(int j = 0 ; j < 9 ; j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
flag = 1;
return ;
}
int x = k/9; // k表示第幾個,則k/9則可知道當前格子在第幾行

int y = k%9; //同理,k%9可知道當前格子在第幾列
if(a[x][y]>0) // 如果a[x][y]>0 ,說明當前格子已經填過數字了 ,則直接進入下一個格子即可
dfs(k+1);
else{
for(int i = 1 ; i <= 9 ; i++){ //i表示想填入的數字
if(!h[x][i]&&!l[y][i]&&!g[pre[x][y]][i]){  // 如果x行,y列,切x行y列所在的9宮格都沒有填入過i,則該i是可能填入的情況之一
h[x][i]=1; // 將x行的i標記為已填過

l[y][i]=1;//將y列的i標記為已填過
g[pre[x][y]][i]=1;//將該x行y列所在的9宮格的i標記為已填過
a[x][y]=i;//將i填入數獨x行y列的格子
dfs(k+1);//進入下一個格子
h[x][i]=0;//如果走到這還沒能輸出,說明該 i 不可行 ,則將該 i 清除 , 接著迴圈i++即可繼續試探下一種可能的i 
l[y][i]=0;
g[pre[x][y]][i]=0;
a[x][y]=0;
}
}
}
}
int main(){
for(int i = 0 ; i < 9 ; i++){
for(int j = 0 ; j < 9 ; j++)
{
cin>>a[i][j];
int x = a[i][j];
h[i][x]=1;
l[j][x]=1;
g[pre[i][j]][x]=1;
}
}
dfs(0); 
return 0;
}