POJ 2676 Sudoku DFS+回溯+减枝

来源:互联网 发布:淘宝网页版卖家中心 编辑:程序博客网 时间:2024/05/17 23:08

点击打开链接

题意:把一个9行9列的网格,

再细分为9个3*3的子网格,要求每行、每列、每个子网格内都只能使用一次1~9中的一个数字
,即每行、每列、每个子网格内都不允许出现相同的数字。

思路:
用三个数组进行标记每行、每列、每个子网格已用的数字,用于剪枝
bool row[10][10];    //row[i][x]  标记在第i行中数字x是否出现了
bool col[10][10];    //col[j][y]  标记在第j列中数字y是否出现了
bool grid[10][10];   //grid[k][z] 标记在第k个3*3子格中数字z是否出现了

DFS试探,下一层匹配失败则回溯


#include<iostream>#include<cstring>#include<cstdio>#include<cstdlib>#include<cmath>#include<algorithm>#include<queue>#include<set>#define PI acos(-1)#define eps 0.00000001using namespace std;int a[11][11];char s[11];int Lvis[11][11],Rvis[11][11],vis[11][11];          int flag=0;int DFS(int x,int y){    if(x==10)        return 1;    if(!a[x][y])    {        int k=(x-1)/3*3+(y-1)/3+1;        for(int i=1; i<=9; i++)        {            if(!Rvis[x][i]&&!Lvis[y][i]&&!vis[k][i])                      {                a[x][y]=i;                Rvis[x][i]=Lvis[y][i]=vis[k][i]=1;                if(y==9)                                        ///遍历下一层                    flag=DFS(x+1,1);                else                    flag=DFS(x,y+1);                if(flag==0)    ///flag==0  表示下一层匹配失败     需要回溯                {                     ///说明上面的赋值有问题                     a[x][y]=0;                     Rvis[x][i]=Lvis[y][i]=vis[k][i]=0;                }            }        }    }    else    {        if(y==9)            flag=DFS(x+1,1);        else            flag=DFS(x,y+1);        if(flag==0)           ///flag==0  表示下一层匹配失败     需要回溯                               ///说明上面的赋值有问题        return 0;        else             return 1;    }    if(!a[x][y])                   ///表示匹配失败了    return 0;    else    return 1;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        flag=0;        memset(vis,0,sizeof(vis));        memset(Lvis,0,sizeof(Lvis));        memset(Rvis,0,sizeof(Rvis));        for(int i=1; i<=9; i++)        {            scanf("%s",s);            for(int j=1; j<=9; j++)            {                a[i][j]=s[j-1]-'0';                if(a[i][j])                {                    int k=(i-1)/3*3+(j-1)/3+1;                    Rvis[i][a[i][j]]=1;                    Lvis[j][a[i][j]]=1;                    vis[k][a[i][j]]=1;                        }            }        }        DFS(1,1);        for(int i=1; i<=9; i++)        {            for(int j=1; j<=9; j++)            {                printf("%d",a[i][j]);            }            printf("\n");        }    }    return 0;}


0 0