POJ_2676_Sudoku

18 篇文章 0 订阅
11 篇文章 0 订阅

数独,当年一家人都很疯狂的玩

如今用电脑dfs非常容易的就解决了。

判断在同一大格里可以填有点麻烦。

题目每组输入其实是9个整数,所以……

另外就是题目要求对于有多个解的题目,输出一个可行解。

#include <iostream>
#include <stdio.h>
using namespace std;

int ss[9];                       //输入这里也卡了一下
int s[9][9];

int f;

bool cilr(int x,int y,int n)             //判断是不是在同一行同一列
{
    for(int i=0;i<9;i++)
        if(n==s[x][i]||n==s[i][y])
            return 0;
    return 1;
}

bool cibox(int x,int y,int n)            //判断是不是在同一个小格子里
{
    int px,py;
    if(x<3)  px=0;
    else if(x>5)  px=6;
    else     px=3;
    if(y<3)  py=0;
    else if(y>5)  py=6;
    else     py=3;
    for(int i=px;i<px+3;i++)
        for(int j=py;j<py+3;j++)
            if(s[i][j]==n)
                 return 0;
    return 1;
}

void shows()                          //打印数独
{
    for(int i=0;i<9;i++)
    {
        for(int j=0;j<9;j++)
            printf("%d",s[i][j]);
        printf("\n");
    }
}

void clear()                        //清空数独
{
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++)
            s[i][j]=0;
}

void dfs(int x,int y)
{
    if(f)                            //这个标记用来确定答案是否出现了
        return;
    if(x==9)                         //数独填完了
    {
        shows();
        f=1;
        return;
    }
    if(s[x][y])                      //已经填了x,y那么下个格子
    {
        if(y<8)
            dfs(x,y+1);
        else
            dfs(x+1,0);
    }
    else
    {
        for(int i=1;i<=9;i++)
        {
            if(cilr(x,y,i)&&cibox(x,y,i))
            {
                s[x][y]=i;
                //cout<<i;
                dfs(x,y);
                //cout<<"re"<<endl;              //第一次总是在中间停住
            }
        }
        s[x][y]=0;                               //这个语句很关键,最开始想的是从左向右从上到下填不会需要
    }                                            //但回退后如果后面的节点回退时没有清空会影响回退后的判断
} 

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        f=0;
        for(int i=0;i<9;i++)
            scanf("%d",&ss[i]);         //注意如果用读整数的方法只能读进来9个整数
        for(int i=0;i<9;i++)
            for(int j=8;j>=0;j--)       //转化为9*9格里面的数
            {
                s[i][j]=ss[i]%10;
                ss[i]/=10;
            }
        dfs(0,0);
        clear();
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值