算法练习-NOJ-1202-数独游戏

时限:1000ms 内存限制:10000K 总时限:3000ms
描述
数独游戏规则
在9阶方阵中,包含了81个小格(九列九行),其中又再分成九个小正方形(称为宫),每宫有九小格。
游戏刚开始时,盘面上有些小格已经填了数字(称为初盘),游戏者要在空白的小格中填入1到9的数字,
使得最后每行、每列、每宫都不出现重复的数字,而且每一个游戏都只有一个唯一的解答(称为终盘)。

输入
一个9*9的矩阵,0表示该位置是空白。

输出
一个9*9的矩阵,格式与输入类似。

输入样例
900050060
020070100
300102040
703800529
000345000
516009403
050208006
007090010
030010004

输出样例
971453268
428976135
365182947
743861529
892345671
516729483
154238796
687594312
239617854

    #include<stdio.h>
#include <windows.h>
int i,j; 
char b[9][9];
int a[9][9];
int temp[9][9];
bool jiOu();
//ASCII 0~9  48~57 a~z  97~122
int main()
{


    void Sudoku(int a[9][9],int n);

    for( i=0;i<9;i++)
    {
        for( j=0;j<9;j++)  
            scanf("%c",&b[i][j]);
        getchar();
    }
    for( i=0;i<9;i++)
    {
        for( j=0;j<9;j++)
            if(b[i][j]>='a'&&b[i][j]<='z')
                a[i][j]=0;
            else
                a[i][j]=b[i][j]-'0';

    }

    Sudoku(a,0);

    return 0;
}

//输出可行的解
void print(int a[9][9])
{

        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
            {
                printf("%d",a[i][j]);
            }
                    printf("\n");

        }

}

//判断是否可以将第i行、第j列的数设为k
bool check(int a[9][9],int i,int j,int k)
{
    int m,n;
    //判断行
    for(n=0;n<9;n++)
    {
        if(a[i][n] == k)
            return false;
    }
    //判断列
    for(m=0;m<9;m++)
    {
        if(a[m][j] == k)
            return false;
    }
    //判断所在小九宫格
    int t1=(i/3)*3,t2=(j/3)*3;
    for(m=t1;m<t1+3;m++)
    {
        for(n=t2;n<t2+3;n++)
        {
            if(a[m][n] == k)
                return false;
        }
    }
    //可行,返回true
    return true;
}

//数独求解函数
void Sudoku(int a[9][9],int n)
{
    int i,j;
    for(i=0;i<9;i++)
    {
        for(j=0;j<9;j++)
            temp[i][j]=a[i][j];
    }
    i=n/9; j=n%9; //求出第n个数的行数和列数
    if(a[i][j] != 0) //已经有原始数据
    {
        if(n == 80)   //是最后一个格子,输出可行解
        {
                print(temp);
        }
        else    //不是最后一个格子,求下一个格子
            Sudoku(temp,n+1);
    }
    else    //没有数据
    {
        for(int k=1;k<=9;k++)
        {
            bool flag=check(temp,i,j,k);
            if(flag) //第i行、第j列可以是k
            {
                temp[i][j]=k; //设为k
                if(n == 80)
                {
                        print(temp);
                }
                else
                    Sudoku(temp,n+1);
                temp[i][j]=0; //恢复为0,判断下一个k
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值