codevs2924数独挑战 深度优先搜索

题目链接:loi_dqs Orz

题目描述:

“芬兰数学家因卡拉,花费3个月时间设计出了世界上迄今难度最大的数独游戏,而且它只有一个答案。因卡拉说只有思考能力最快、头脑最聪明的人才能破解这个游戏。”这是英国《每日邮报》2012年6月30日的一篇报道。这个号称“世界最难数独”的“超级游戏”,却被扬州一位69岁的农民花三天时间解了出来。

看到这个新闻后,我激动不已,证明我们OI的实力的机会来了,我们虽然不是思考能力最快、头脑最聪明的人,但是我们可以保证在1s之内解题。

好了废话不多说了……

数独是一种填数字游戏,英文名叫Sudoku,起源于瑞士,上世纪70年代由美国一家数学逻辑游戏杂志首先发表,名为Number Place,后在日本流行,1984年将Sudoku命名为数独,即“独立的数字”的省略,解释为每个方格都填上一个个位数。2004年,曾任中国香港高等法院法官的高乐德(Wayne Gould)把这款游戏带到英国,成为英国流行的数学智力拼图游戏。

 玩家需要根据9×9盘面上的已知数字,推理出所有剩余位置(数据表示为数字0)的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1-9,不重复。

现在给你一个数独,请你解答出来。每个数独保证有解且只有一个。-

输入描述:

9行9列。每个数字用空格隔开。0代表要填的数,行末没有空格,末尾没有回车。

输出描述:

输出答案。
排成9行9列。

核心:把点哈希成一个值,并且每次可以对这个值映射出它的坐标,这可以通过取摸和整除来实现。深搜,对于每个值判断当前点有没有值,如果有,跑下一个点,如果没有,枚举1~9的的数,暴力判断每个数是否能填,能填就试一下,如果到达了81并且当前点填上了数,这就是一个可行数独的解,停止继续搜索。记得试完回溯~.

其实在简单的数独中不用加入A*优化,所以这个题并不用A*,数据范围体现了这一点,那这个题就是一个枚举+暴力检验的深搜了。

代码:

#include
#include
#include
#include
using namespace std;
const int size = 11;
int maps[size][size];

bool judge(int k,int p)
{
    int x = k / 9 + 1;
    int y = k % 9;
    if(y == 0)  y = 9,x --;
    int tx,ty;
    if(x <= 3)  tx = 1;
    else if(x > 3 && x <= 6)    tx = 4;
    else if(x > 6 && x <= 9)    tx = 7;
    if(y <= 3)  ty = 1;
    else if(y > 3 && y <= 6)    ty = 4;
    else if(y > 6 && y <= 9)    ty = 7;
    for(int i = 1;i <= 9;i ++)
    {
        if(maps[x][i] == p) return false;
        if(maps[i][y] == p) return false;
    }
    for(int i = tx;i <= tx + 2;i ++)
    {
        for(int j = ty;j <= ty + 2;j ++)
        {
            if(maps[i][j] == p) return false;
        }
    }
    return true;
}
bool flag = 1;
void dfs(int k)
{
    if(k > 81)
    {
        for(int i = 1;i <= 9;i ++)
        {
            for(int j = 1;j <= 9;j ++)
            {
                printf("%d ",maps[i][j]);
            }
            puts("");
        }
        exit(0);
    }
    int x = k / 9 + 1;
    int y = k % 9;
    if(y == 0)  y = 9,x --;
//  cout<
    int tx,ty;
    if(x <= 3)  tx = 1;
    else if(x > 3 && x <= 6)    tx = 4;
    else if(x > 6 && x <= 9)    tx = 7;
    if(y <= 3)  ty = 1;
    else if(y > 3 && y <= 6)    ty = 4;
    else if(y > 6 && y <= 9)    ty = 7;
//  if(ty > 9)  ty -= 3;
//  cout<
//  cout<
    if(maps[x][y])
    {
        dfs(k+1);
    }
    else if(flag)
    {
        for(int i = 1;i <= 9;i ++)
        {
            if(judge(k,i))
            {
                maps[x][y] = i;
//              if(k == 81) exit(0);
                dfs(k+1);
                maps[x][y] = 0;
            }
        }
    }
}

int main()
{
    for(int i = 1;i <= 9;i ++)
        for(int j = 1;j <= 9;j ++)
        {
            scanf("%d",&maps[i][j]);
        }
    dfs(1);
    for(int i = 1;i <= 9;i ++)
    {
        for(int j = 1;j <= 9;j ++)
        {
            printf("%d ",maps[i][j]);
        }
        puts("");
    }
    return 0;
}

/*
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
*/

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