1026-Sudoku Killer

Problem Description
自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视。<br>据说,在2008北京奥运会上,会将数独列为一个单独的项目进行比赛,冠军将有可能获得的一份巨大的奖品———HDU免费七日游外加lcy亲笔签名以及同hdu acm team合影留念的机会。<br>所以全球人民前仆后继,为了奖品日夜训练茶饭不思。当然也包括初学者linle,不过他太笨了又没有多少耐性,只能做做最最基本的数独题,不过他还是想得到那些奖品,你能帮帮他吗?你只要把答案告诉他就可以,不用教他是怎么做的。<br><br>数独游戏的规则是这样的:在一个9x9的方格中,你需要把数字1-9填写到空格当中,并且使方格的每一行和每一列中都包含1-9这九个数字。同时还要保证,空格中用粗线划分成9个3x3的方格也同时包含1-9这九个数字。比如有这样一个题,大家可以仔细观察一下,在这里面每行、每列,以及每个3x3的方格都包含1-9这九个数字。<br><br>例题:<br><img src=/data/images/C31-1001-1.jpg><br><br>答案:<br><img src=/data/images/C31-1001-2.jpg><br>
 

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

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

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

Sample Output
   
   
   
   
7 1 2 4 6 9 3 5 8<br>3 6 5 2 8 7 1 9 4<br>4 9 8 5 1 3 6 7 2<br>9 2 4 1 5 6 8 3 7<br>5 7 6 3 9 8 2 4 1<br>1 8 3 7 2 4 9 6 5<br>2 3 1 9 7 5 4 8 6<br>6 4 7 8 3 2 5 1 9<br>8 5 9 6 4 1 7 2 3<br>
 

Author
linle
 

Source
ACM暑期集训队练习赛(三)


1.题号:1026-Sudoku Killer

2.题意:九个九宫格,行列及每个九宫格中只有1-9这九个数字有且只有一个;
             输入?代表该处需要填数。注意输出,从第二组数据后开始输出空行,每行最后不应该有空格。
3.解题思路:定义一个结构体,存储?的位置(行列),输入处理char》int,进行深搜,于每一个点开始从1-9填数,
                    >限定条件是行,列,九宫格不重复元素(代码标注一些)

4.感想:比较难吧,但做出来又不感觉那么难了,主要就是数据处理,输入输出的处理比较费事;还有dfs,毕竟不熟,多练既是              巧,百炼成钢!

5.AC代码:


#include<stdio.h>
#include<string.h>

using namespace std;

int a[10][10];
int flag;
int num,cnt;//存放?的个数,并计数

struct q
{
    int q_x;
    int q_y;
}que[100];//存放问号的位置

int ok(int x,int y,int n)//在x,y位置放值为n的数
{
    int i,j,xx,yy,xxx,yyy;

    for(i=0;i<9;i++)//列,行中的数据是否冲突
        if(a[i][x]==n)
            return 0;
    for(i=0;i<9;i++)
        if(a[y][i]==n)
            return 0;

        xx=x/3*3;//所在九宫格,xx为开始,xxx为结束
        yy=y/3*3;
        xxx=xx+3;
        yyy=yy+3;

        for(i=yy;i<yyy;i++)
            for(j=xx;j<xxx;j++)
                if(a[i][j]==n)
                    return 0;//有重值
        return 1;//没找到重值
}

void dfs(int cnt)//深搜
{
    int i;
    if(flag)
        return;
    if(cnt==num)//?已全部搜完
    {
        flag=1;
        return;
    }
    for(i=1;i<=9;i++)
        if(ok(que[cnt].q_x,que[cnt].q_y,i))//依此填数
        {
            a[que[cnt].q_y][que[cnt].q_x]=i;
            dfs(cnt+1);
            if(flag==1)
                return;
            a[que[cnt].q_y][que[cnt].q_x]=0;
        }
}

int main()
{
    int x,y,i,j,t=0;
    char ch[2];
    while(scanf("%s",&ch)!=EOF)//先读取1个char
    {
        num=0;
        cnt=0;
        flag=0;

        if(ch[0]!='?')//不是问号就存数
            a[0][0]=ch[0]-'0';
        else//存储?的位置
        {
            a[0][0]=0;
            que[num].q_y=0;
            que[num++].q_x=0;
        }

        for(y=0;y<9;y++)
        {
            for(x=0;x<9;x++)
            {
                if(x==0&&y==0)
                    continue;
                scanf("%s",&ch);
                if(ch[0]!='?')//同上
                    a[y][x]=ch[0]-'0';
                else
                {
                    a[y][x]=0;
                    que[num].q_y=y;
                    que[num++].q_x=x;
                }
            }
        }

        dfs(0);

        if(t++)//空行
            printf("\n");

        for(i=0;i<9;i++)//输出格式
        {
            for(j=0;j<8;j++)
            {
                printf("%d ",a[i][j]);
            }
            printf("%d\n",a[i][8]);
        }
    }
    return 0;
}

你可能感兴趣的:(搜索)