杭电1426--Sudoku Killer(深搜)

该博客主要介绍了如何解决杭电1426题——Sudoku Killer,使用深度优先搜索(DFS)算法进行数独填充。通过检查数字在行、列和宫格内的唯一性来确定正确答案。代码中包含输入数独矩阵的处理和DFS的实现细节。
摘要由CSDN通过智能技术生成
Problem Description
自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视。
据说,在2008北京奥运会上,会将数独列为一个单独的项目进行比赛,冠军将有可能获得的一份巨大的奖品———HDU免费七日游外加lcy亲笔签名以及同hdu acm team合影留念的机会。
所以全球人民前仆后继,为了奖品日夜训练茶饭不思。当然也包括初学者linle,不过他太笨了又没有多少耐性,只能做做最最基本的数独题,不过他还是想得到那些奖品,你能帮帮他吗?你只要把答案告诉他就可以,不用教他是怎么做的。

数独游戏的规则是这样的:在一个9x9的方格中,你需要把数字1-9填写到空格当中,并且使方格的每一行和每一列中都包含1-9这九个数字。同时还要保证,空格中用粗线划分成9个3x3的方格也同时包含1-9这九个数字。比如有这样一个题,大家可以仔细观察一下,在这里面每行、每列,以及每个3x3的方格都包含1-9这九个数字。

例题:
杭电1426--Sudoku <wbr>Killer(深搜)

答案:
杭电1426--Sudoku <wbr>Killer(深搜)
 

Input
本题包含多组测试,每组之间由一个空行隔开。每组测试会给你一个 9*9 的矩阵,同一行相邻的两个元素用一个空格分开。其中1-9代表该位置的已经填好的数,问号(?)表示需要你填的数。
 

Output
对于每组测试,请输出它的解,同一行相邻的两个数用一个空格分开。两组解之间要一个空行。
对于每组测试数据保证它有且只有一个解。
 

Sample Input
7 1 2 ? 6 ? 3 5 8 ? 6 5 2 ? 7 1 ? 4 ? ? 8 5 1 3 6 7 2 9 2 4 ? 5 6 ? 3 7 5 ? 6 ? ? ? 2 4 1 1 ? 3 7 2 ? 9 ? 5 ? ? 1 9 7 5 4 8 6 6 ? 7 8 3 ? 5 1 9 8 5 9 ? 4 ? ? 2 3
 

Sample Output
7 1 2 4 6 9 3 5 8 3 6 5 2 8 7 1 9 4 4 9 8 5 1 3 6 7 2 9 2 4 1 5 6 8 3 7 5 7 6 3 9 8 2 4 1 1 8 3 7 2 4 9 6 5 2 3 1 9 7 5 4 8 6 6 4 7 8 3 2 5 1 9 8 5 9 6 4 1 7 2 3
 
//
一个多月没写C语言了,这算是个开篇吧!这个数独是一个多月前写的,未能解决,找不到某个地方出错了,就扔在CSDN上了!今天早上打开CSDN上的博客,已有达人给了提示,确实是在读取时,出现了错误!算法上就是个简单的深搜,这里就不说了!

# include<stdio.h>

# include<string.h>

struct node{

    int x,y;

};

struct node point[100];

char map[10][10];

int k,n,t,flag;

int check(int n,int x,int y)

{

    int i,j;

    for(i=0;i<9;i++)

      if(map[x][i]-'0'==n)

          return 0;

    for(i=0;i<9;i++)

      if(map[i][y]-'0'==n)

          return 0;

    for(i=x/3*3;i<=x/3*3+2;i++)

        for(j=y/3*3;j<=y/3*3+2;j++)

            if(map[i][j]-'0'==n)

                return 0;

    return 1;

}

void DFS(int n)

{

    int i,j;

    if(n==k)

    {

        i=0;

              if(flag)

                     printf("\n");

        for(i=0;i<9;i++)

        {

            for(j=0;j<9;j++)

            {

                if(j==0)

                    printf("%c",map[i][j]);

                else

                    printf(" %c",map[i][j]);

            }

            printf("\n");

        }

        return ;

    }

    for(i=1;i<=9;i++)

    {

        if(check(i,point[n].x,point[n].y))

        {

            map[point[n].x][point[n].y]=i+'0';

            DFS(n+1);

            map[point[n].x][point[n].y]='?';

        }

    }

              

int main()

{

  int i,j;

  flag=0;

  do //改 while(scanf("%c %c %c %c %c %c %c %c %c",&map[0][0],&map[0][1],&map[0][2],&map [0][3],&map[0][4],&map[0][5],&map[0][6],&map[0][7],&map[0][8])!=EOF)//读取数独的第一行

  {

    //改 getchar();

    for(i=0;i<=8;i++) //改 for(i=1;i<=8;i++)//for循环读取剩余的八行

    {

    scanf("%c %c %c %c %c %c %c %c %c",&map[i][0],&map[i][1],&map[i][2],&map[i][3],&map[i][4],&map[i][5],&map[i][6],&map[i][7],&map[i][8]);

    getchar();

    }

    k=0;

    for(i=0;i<9;i++)

    for(j=0;j<9;j++)

    if(map[i][j]=='?')//记录要填的数的位置,k为未知数“?”的个数

    {

    point[k].x=i;

    point[k++].y=j;

    }

    DFS(0);//开始深搜

       flag=1;

  } while(getchar() == '\n');//加

  return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值