dfs例題——四階數獨
阿新 • • 發佈:2020-12-12
例題:給出一個4×4的方格,每個格子只能填1~4的整數,要求每行、每列和四等分更小的正方形部分都剛好由1~4組成。
問:一共有多少種合法的填寫方法並輸出這些填寫方法。
分析:如果用窮舉的方法,就得使用16層for迴圈,會有4^16約為42億種情況,這樣處理起來就會很低效。
為了提高效率,所以應當做到一發現某個數字不符合要求,就終止並進行下一次情況。
```cpp
//四階數獨的個數並輸出如何填數(深度優先搜尋(dfs))
#include<bits/stdc++.h>
#define N 5
using namespace std;
int a[N*N],n=4*4,ans=0;
int r[N][N],c[N][N],sq[N][N];
void dfs(int x)
{
if(x>n)
{
ans++;//如果數已經填滿,就加一次結果的數量
for(int i=1;i<=n;i++)//輸出填數方案
{
cout << a[i] << ' ' ;
if(i%4==0)putchar(10);
}
putchar(10);
return;
}
int row=(x-1)/4+1;//填入數字所在的行
int col=(x-1)%4+1;//填入數字所在的列
int block=(row-1)/2*2+(col-1)/2+1;//填入數字所在的小方塊
for(int i=1;i<=4;i++)
{
if(r[row][i]==0&&c[col][i]==0&&sq[block][i]==0)
{
a[x]=i;//記錄填的數
r[row][i]=1,c[col][i]=1,sq[block][i]=1;//標記行,列,小方塊內已有這個數
dfs(x+1);//進行下一次遞迴
r[row][i]=0,c[col][i]=0,sq[block][i]=0;//回溯以後取消佔位
}
}
}
int main()
{
dfs(1);
cout << ans << endl ;
return 0;
}
```