sudoku,数独,poj2676

每次从状态数最小的位置开始搜索

#include <cstdio>
#include <cstring>
using namespace std;

int g[9][9];
int row[9][10];
int col[9][10];
int cell[9][10];

int getId(int x,int y){
    return (x/3)*3 + y/3;
}

void printans(){
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            printf("%d",g[i][j]);
        }
    printf("
");
    }
}

int flag = 1;

void dfs(int n){
    if(n==0){
        flag = 0;
        printans();
        return;
    }
    int small = 10;
    int x,y;
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            if(g[i][j]==0){
                int cnt = 0;
                for(int k=1;k<=9;k++){
                    cnt += (row[i][k]+col[j][k]+cell[getId(i,j)][k]==0);
                }
                if(cnt<small){
                    small = cnt;
                    x=i;y=j;
                }
            }
        }
    }
    if(small==0||small==10) return;
    for(int k=1;k<=9;k++){
        if(row[x][k]+col[y][k]+cell[getId(x,y)][k]==0&&flag){
            g[x][y] = k;
            row[x][k]=col[y][k]=cell[getId(x,y)][k]=1;
            dfs(n-1);
            g[x][y] = 0;
            row[x][k]=col[y][k]=cell[getId(x,y)][k]=0;
        }
    }
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        memset(row,0,sizeof(row));
        memset(col,0,sizeof(col));
        memset(cell,0,sizeof(cell));
        int ct_zero = 0;
        for(int i=0;i<9;i++){
            char s[20];
            scanf("%s",s);
            for(int j=0;j<9;j++){
                g[i][j]=s[j]-'0';
                row[i][g[i][j]]=1;
                col[j][g[i][j]]=1;
                cell[getId(i,j)][g[i][j]]=1;
                ct_zero += g[i][j]==0;
            }
        }
        flag = 1;
        dfs(ct_zero);    
    }
}
原文地址:https://www.cnblogs.com/zhjou/p/4759830.html