POJ2676 Sudoku - DFS

POJ2676 Sudoku

传送门

题意:

填充未完成的数独。。。(就这么简单。。。。

思路:

爆搜即可。
可行性剪枝:用三个\(bool\)数组分别记录行、列、\(3*3\)的块中,\(9\)种数字的使用情况

AC Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=9+10;
char s[N][N];int mp[N][N];
int blo[N][N];bool hang[N][N],lie[N][N],kuai[N][N];
int ans[N][N];
void pre(){
    memset(ans,0,sizeof(ans));memset(mp,0,sizeof(mp));
    memset(hang,0,sizeof(hang));memset(lie,0,sizeof(lie));memset(kuai,0,sizeof(kuai));
}
bool che(int x,int y,int k){
    if(hang[x][k]||lie[y][k]||kuai[blo[x][y]][k]) return false;
    return true;
}
bool dfs(int x,int y){
    if(x==10){return true;}
    if(mp[x][y]){ bool f=0;if(y+1<=9) f=dfs(x,y+1);else f=dfs(x+1,1); return f;} 
    for(int i=1;i<=9;i++){
        if(che(x,y,i)){
            hang[x][i]=lie[y][i]=kuai[blo[x][y]][i]=1;
            ans[x][y]=i;bool f=0;
            if(y+1<=9) f=dfs(x,y+1); else f=dfs(x+1,1);
            if(f) return true;
            hang[x][i]=lie[y][i]=kuai[blo[x][y]][i]=0;
        }
    }return false;
}
int main(){
    int t;scanf("%d",&t);
    for(int i=3;i<=9;i+=3){ for(int j=1;j<=9;j++){ if(j<=3) blo[i-2][j]=blo[i-1][j]=blo[i][j]=1+(i-3); else if(j<=6) blo[i-2][j]=blo[i-1][j]=blo[i][j]=2+(i-3); else if(j<=9) blo[i-2][j]=blo[i-1][j]=blo[i][j]=3+(i-3);}}
    while(t--){
        pre();
        for(int i=1;i<=9;i++) scanf("%s",s[i]+1);
        for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) ans[i][j]=mp[i][j]=s[i][j]-'0',hang[i][mp[i][j]]=lie[j][mp[i][j]]=kuai[blo[i][j]][mp[i][j]]=1;
//      for(int i=1;i<=9;i++) { for(int j=1;j<=9;j++) printf("%d",mp[i][j]);printf("\n");}
        dfs(1,1);
        for(int i=1;i<=9;i++){for(int j=1;j<=9;j++) printf("%d",ans[i][j]);printf("\n");}
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Loi-Brilliant/p/9611092.html