DFS解数独,以及如何生成数独

这个是我之前写过的一个DFS解数独的代码。记录数独的xzy三轴的状态来进行改变。写的比较垃圾,由于我当时没看出来九宫格关于xy两个轴的规律,所以还专门暴力写了一个函数来判断要怎么处理这个东西。
这是输入
这是输出

#include<stdio.h>
#include<algorithm>
#include<string.h>
bool visx[155][155];///记录xyz上状态
bool visy[155][155];
bool visz[155][155];
char Mapold[155][155];
int Map[155][155];
int flag = 0;
void z(int x,int y,int num,int gao)///改变z轴状态的
{
    if(x <= 3 && y <= 3)
    {
        if(gao)
            visz[1][num] = 1;
        else
            visz[1][num] = 0;
    }
    else if(x > 3 && x <= 6 && y <= 3)
    {
        if(gao)
            visz[2][num] = 1;
        else
            visz[2][num] = 0;
    }
    else if(x > 6 && x <= 9 && y<= 3)
    {
        if(gao)
            visz[3][num] = 1;
        else
            visz[3][num] = 0;
    }
    else if(x <= 3 && y > 3 && y<= 6)
    {
        if(gao)
            visz[4][num] = 1;
        else
            visz[4][num] = 0;
    }
    else if( x <= 3 && y > 6 && y<=9)
    {
        if(gao)
            visz[7][num] = 1;
        else
            visz[7][num] = 0;
    }
    else if(x > 3 && x <= 6 && y > 3 && y<=6)
    {
        if(gao)
            visz[5][num] = 1;
        else
            visz[5][num] = 0;
    }
    else if(x > 6 && x <= 9 && y> 3 && y <= 6)
    {
        if(gao)
            visz[6][num] = 1;
        else
            visz[6][num] = 0;
    }
    else if(x > 3 && x<= 6 && y > 6 && y<=9)
    {
        if(gao)
            visz[8][num] = 1;
        else
            visz[8][num] = 0;
    }
    else
    {
        if(gao)
            visz[9][num] = 1;
        else
            visz[9][num] = 0;
    }
}
int checkz(int x,int y,int num)///检查z轴状态,进行改变
{
    if(x <= 3 && y <= 3)
    {
        return visz[1][num] ;
    }
    else if(x > 3 && x <= 6 && y <= 3)
    {
        return  visz[2][num] ;
    }
    else if(x > 6 && x <= 9 && y<= 3)
    {
        return  visz[3][num];
    }
    else if(x <= 3 && y> 3 && y<= 6)
    {
        return visz[4][num] ;
    }
    else if( x <= 3 && y > 6 && y<=9)
    {
        return  visz[7][num];
    }
    else if(x > 3 && x <= 6 && y > 3 && y<=6)
    {
        return  visz[5][num] ;
    }
    else if(x > 6 && x <= 9 && y> 3 && y <= 6)
    {
        return visz[6][num] ;
    }
    else if(x > 3 && x<= 6 && y > 6)
    {
        return  visz[8][num] ;
    }
    else
        return   visz[9][num] ;
}
void dfs(int x,int y)
{
    if(flag)
        return ;
    if(x==9 && y==9 && !flag)
    {
        flag = 1;
        for(int i = 1; i<= 9 ; i++)
        {
            for(int j = 1; j <= 9 ; j++)
            {
                printf("%d",Map[i][j]);
            }
            puts("");
        }

        return ;
    }
    if(x > 9 && flag )
        return ;
    if(y+1 > 9)
    {
        if(Mapold[x+1][1]!='0')
        {
            dfs(x+1,1);
        }
        else
        {
            for(int i = 1; i<= 9 ; i++)
            {

                if(!visx[x+1][i] && !visy[1][i] && checkz(x+1,1,i)==0)
                {
                    visx[x+1][i] = 1;
                    visy[y+1][i] = 1;
                    z(x+1,1,i,1);
                    Map[x+1][1] = i;
                    dfs(x+1,1);
                    Map[x+1][1] = 0;
                    z(x+1,1,i,0);
                    visx[x+1][i] = 0;
                    visy[1][i] = 0;
                }
            }
        }
    }
    else
    {
        if(Mapold[x][y+1]!='0')
        {
            dfs(x,y+1);
        }
        else
        {
            for(int i = 1; i<=9; i++)
            {
                if(!visx[x][i] && !visy[y+1][i] && checkz(x,y+1,i)==0)
                {
                    visx[x][i] = 1;
                    visy[y+1][i] = 1;
                    z(x,y+1,i,1);
                    Map[x][y+1] = i;
                    dfs(x,y+1);
                    Map[x][y+1] = 0;
                    z(x,y+1,i,0);
                    visx[x][i] = 0;
                    visy[y+1][i] = 0;
                }
            }
        }
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
        {flag = 0;
        memset(visx,0,sizeof(visx));
        memset(visy,0,sizeof(visy));
        memset(visz,0,sizeof(visz));
        memset(Mapold,0,sizeof(Mapold));
        memset(Map,0,sizeof(Map));
        for(int i = 1; i<= 9; i++)
        {
            scanf("%s",Mapold[i]+1);
        }
        for(int i =1; i<=9; i++)
        {
            for(int j = 1; j<=9; j++)
            {
                Map[i][j] = Mapold[i][j]-'0';
                if(Map[i][j])
                {
                    visx[i][Map[i][j]] = 1;
                    visy[j][Map[i][j]] = 1;
                    z(i,j,Map[i][j],1);
                }
            }
        }
        dfs(1,0);
        if(flag == 0)
            for(int i = 1; i<= 9 ; i++)
            {
                for(int j = 1; j<= 9 ; j++)
                {
                    printf("%c",Mapold[i][j]);
                }
                puts("");
            }
    }

}

生成数独的方法如下:
你得到一个数独的解后,进行n次行或者列的变换,变化规则如下:设需要变化的两个数为x,y。那么第一次行列变换,则将所有行列的x,y互换位置。这就完成了第一次行列变换,进行n次后,再挖空数独,就能造出来一个数独了。但是这个方法我也不知道能不能制造出所有数独。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值