【DFS】Ybt_數獨遊戲
阿新 • • 發佈:2021-01-10
技術標籤:DFS
題目大意
給你一些數獨題,讓你填。
空位以 ‘.’ 表示,多組資料,以end結尾。
解
深度搜索,剪枝。
用二進位制位壓縮儲存狀態,用這個以判斷當前位置可以填的數字。
程式碼
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int l[20], h[20], z[5][5], k[20][20], flag;
char c;
char getc(){ //輸入
char lc = getchar();
while(( lc> '9' || lc<'0' ) && lc != '.' && lc != 'e') lc = getchar();
return lc;
}
void init(){ //輸入
memset(l, 0, sizeof(l));
memset(h, 0, sizeof(h));
memset(z, 0, sizeof(z));
for(int i = 1; i <= 9; ++i){
for(int j = 1; j <= 9; ++j){
if(c != '.'){
k[i][j] = c-48;
l[ j] += 1 << (c-48-1); //列,這個數的狀態為1(填過)
h[i] += 1 << (c-48-1); //行,這個數的狀態為1(填過)
z[(i+2)/3][(j+2)/3] += 1 << (c-48-1); //小矩陣,這個數的狀態為1(填過)
}
else k[i][j] = 0;
c = getc();
}
}
}
void printt(){ //輸出
for(int i = 1; i <= 9; ++i)
for(int j = 1; j <= 9; ++j)
printf("%d", k[i][j]);
printf("\n");
}
void dfs(int bh){
if(bh > 81){ //找到答案
flag = 1;
printt();
return;
}
int x = (bh+8) / 9, y = (bh-1) % 9 + 1; //當前點座標
int jzx = (x+2) / 3, jzy = (y+2) / 3; //小矩陣是哪一個
if(k[x][y] != 0) dfs(bh + 1); //如果它本來就給出了這個數
else for(int i = 1; i <= 9; ++i){ //列舉
if((h[x] >> (i-1)) % 2 == 0) //行沒出現
if((l[y] >> (i-1)) % 2 == 0) //列沒出現
if((z[jzx][jzy] >> (i-1)) % 2 == 0){ //小矩陣沒出現
h[x] += 1 << (i-1); //改變狀態
l[y] += 1 << (i-1);
z[jzx][jzy] += 1 << (i-1);
k[x][y] = i; //記錄答案
dfs(bh+1);
k[x][y] = 0;
if(flag == 1) return;
h[x] -= 1 << (i-1);
l[y] -= 1 << (i-1);
z[jzx][jzy] -= 1 << (i-1);
}
}
}
int main(){
c = getc();
while(c!='e'){ //多組資料
init();
flag = 0;
dfs(1);
}
}