数独

传送门


  其实这题还是比较水的。(主要是写代码的时候以为枚举判断能够过(就写了300+行),最后还T了。

  只要加三个判断数组vis1 , vis2 ,vis 3 , 分别判断该格子的行、列、宫内的数字有哪些被用过。加上无脑搜索就A了。

  有个小坑:本题的输出要放在DFS内,不然搜索回溯后,建好的新图就被清空了。

AC代码:

#include<cstdio>
#include<cstdlib>
using namespace std;
int dt[10][10],vis1[10][10],vis2[10][10],vis3[10][10];
inline int read()
{
    char kr=0;
    char ls;
    for(;ls>'9'||ls<'0';kr=ls,ls=getchar());
    int xs=0;
    for(;ls>='0'&&ls<='9';ls=getchar())
    {
        xs=xs*10+ls-48;
    }
    if(kr=='-') xs=0-xs;
    return xs;
}
inline void print()
{
    for(int i=1;i<=9;i++)
    {
        for(int j=1;j<=9;j++)
            printf("%d ",dt[i][j]);
        printf("
");
    }
    exit(0);//结束程序
}
inline void dfs(int x,int y)
{
    if(x==9&&y==10) print();//打印输出
    if(y==10)
    {
        x+=1,y=1;
    }//换行
    if(dt[x][y]==0)
    {     int tp=0;//特判
        for(int j=1;j<=9;j++)
        {
            int tp1=((x-1)/3)*3,tp2=(y-1)/3,ttp=tp1+tp2;//ttp为第几组
            if(vis1[x][j]==0&&vis2[y][j]==0&&vis3[ttp][j]==0)
            {
                vis1[x][j]=vis2[y][j]=1;
                dt[x][y]=j;
                vis3[ttp][j]=1;
                tp=1;
                dfs(x,y+1);
                vis1[x][j]=vis2[y][j]=0;dt[x][y]=0;vis3[ttp][j]=0;
            }
        }
        if(tp==0) return;//判断,如果不可行,回溯
    }
    else dfs(x,y+1);
}
int main()
{
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
        {
            dt[i][j]=read();
            vis1[i][dt[i][j]]=1;vis2[j][dt[i][j]]=1;
            vis3[((i-1)/3)*3+(j-1)/3][dt[i][j]]=1;//巧妙的记录一个宫内的数字 
        }
    dfs(1,1);
return 0;
}
原文地址:https://www.cnblogs.com/lck-lck/p/9649113.html