10117 : 数独游戏

问题描述
数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。
数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。
给你这样一个九宫格,你能求出这个数独的解么?保证数独有唯一解
输入格式
输入一个输入,每个数字表示对应位置的值,0表示该位置还为填数字。
输出格式
输入数独的解,格式如样例所示,行末无空格.
样例输入
000000000
002301000
000000076
900680000
000000400
001000200
000002104
000070000
600090000
样例输出
598746312
762351948
143829576
925684731
376215489
481937265
837562194
219478653
654193827
原题君~~~

#include <cstdio>

using namespace std;

struct NODE{
    int x, y;
}b[85]; 
int a[10][10];//存储数独 
int ling;//零的个数 
int flag=0;//见dfs中作用 
bool ma[10][10],mb[10][10],mc[10][10];//标记行列宫是否可填某数(空间换时间) 
bool check (int x, int y, int s)
{
    if (ma[x][s]==0&&mb[y][s]==0&&mc[(x-1)/3*3+(y+2)/3][s]==0) 
        return 1;//若横行数列宫格都满足填入的条件则填入
    return 0;//否则不能填 
}//判断坐标(x,y)是否可以填入s这个值 
void dfs (int cnt)
{
    if (cnt == ling+1)
    {
        flag=1;//由于输入保证有且只有一组解,所以找到后可直接返回。
        return;//flag=1表示找到正解,以保证连续返回,不再浪费时间。 
    }//判断条件,若已经填入了所有需填的数,则说明找到了一组正解,返回 
    int x = b[cnt].x;
    int y = b[cnt].y;//坐标的赋值 
    for (int i = 1; i <= 9; i++)//for循环尝试所有可能 
        if (check (x, y, i)==true)
        {
            a[x][y] = i;
            ma[x][i]=1;
            mb[y][i]=1;
            mc[(x-1)/3*3+(y+2)/3][i]=1;//临时认为(x,y)填i 
            dfs (cnt+1);//向下一层搜 
            if(flag) return;//上述flag连续返回的执行 
            a[x][y] = 0;
            ma[x][i]=0;
            mb[y][i]=0;
            mc[(x-1)/3*3+(y+2)/3][i]=0;//返回后发现(x,y)不能填i,取消之前的标记 
        }
}
int main()
{
    for (int i = 1; i <= 9; i++)
        for (int o = 1; o <= 9; o++)
        {
            scanf ("%1d", &a[i][o]);//这样可以做到一位一位读入 
            if (a[i][o]==0)//若这个位置为0 
            {
                ling++;//ling统计需要填入数的格子的数目 
                b[ling].x=i;
                b[ling].y=o;//b数组存储需要搜索的格子的坐标,所以用到了结构体 
            }
            else//否则(即这个位置有确定的值) 
            {
                ma[i][a[i][o]]=1;//标记横行不能填哪些数 
                mb[o][a[i][o]]=1;//标记纵列不能填哪些数 
                mc[(i-1)/3*3+(o+2)/3][a[i][o]]=1;//标记宫格不能填哪些数 
            }
        }//输入 
    dfs (1);//开始搜索! 
    for (int i = 1; i <= 9; i++)
    {
        for (int o = 1; o <= 9; o++)
            printf ("%d", a[i][o]);
        printf ("\n");
    }
    return 0; 
    ********~~~~~~********
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

oj_onecode

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值