题目链接: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<iostream>
#include<cstdio>
#include<cstring>
#include<bits/stdc++.h>
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<<k<<" "<<x<<" "<<y<<" "<<endl;// cout<<tx<<" "<<ty<<endl;
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<<k<<" "<<x<<" "<<y<<" ";
// cout<<tx<<" "<<ty<<endl;
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
*/