Description
自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视。
据说,在2008北京奥运会上,会将数独列为一个单独的项目进行比赛,冠军将有可能获得的一份巨大的奖品―――HDU免费七日游外加lcy亲笔签名以及同hdu acm team合影留念的机会。
所以全球人民前仆后继,为了奖品日夜训练茶饭不思。当然也包括初学者linle,不过他太笨了又没有多少耐性,只能做做最最基本的数独题,不过他还是想得到那些奖品,你能帮帮他吗?你只要把答案告诉他就可以,不用教他是怎么做的。
数独游戏的规则是这样的:在一个9x9的方格中,你需要把数字1-9填写到空格当中,并且使方格的每一行和每一列中都包含1-9这九个数字。同时还要保证,空格中用粗线划分成9个3x3的方格也同时包含1-9这九个数字。比如有这样一个题,大家可以仔细观察一下,在这里面每行、每列,以及每个3x3的方格都包含1-9这九个数字。
例题:
答案:
据说,在2008北京奥运会上,会将数独列为一个单独的项目进行比赛,冠军将有可能获得的一份巨大的奖品―――HDU免费七日游外加lcy亲笔签名以及同hdu acm team合影留念的机会。
所以全球人民前仆后继,为了奖品日夜训练茶饭不思。当然也包括初学者linle,不过他太笨了又没有多少耐性,只能做做最最基本的数独题,不过他还是想得到那些奖品,你能帮帮他吗?你只要把答案告诉他就可以,不用教他是怎么做的。
数独游戏的规则是这样的:在一个9x9的方格中,你需要把数字1-9填写到空格当中,并且使方格的每一行和每一列中都包含1-9这九个数字。同时还要保证,空格中用粗线划分成9个3x3的方格也同时包含1-9这九个数字。比如有这样一个题,大家可以仔细观察一下,在这里面每行、每列,以及每个3x3的方格都包含1-9这九个数字。
例题:
答案:
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
做此题真是肝肠寸断……
首先此题应该用 搜索 来做。
初步构想,通过划分的9个小方格,将每个小方格内带?的地方的可能值列出来,存在vector里,这样搜索的时候只需判断行或者列是否满足规则就可。
然后我就开始搜点了,一个一个搜,结果没做出来……(好笨……)
然后百度了一波大神的,发现他们都是直接搜带?的点,恍然大悟。于是修改代码,加了结构体。
历尽千辛万苦,终于做出答案来了,赶紧提交,超时了……
看到大神写的注意事项,原来用while(1) 会超时,于是改成while(~scanf) ,瞥了一眼大神的就自己改,发现输入直接不对,当时用的str[10] ,和 %s 直接挂了,才看见输入中间有空格,只好仔细研究大神的输入,发现用的str[2],在str[0]取数,空格存在str[1]里 ,极妙的做法,活到老,学到老。
改过来提交,还是超时……好气呀!!!!!
找不出猫饼了……只有用vector存的值,和AC代码不同(直接枚举1到9),没办法,我也改成直接枚举1到9,然后过了。不过还是想不通为什么用vector存可能值会超时……
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <list>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
using namespace std;
typedef struct WH{ ///用结构体存储 ? 的坐标
int x;
int y;
}wh;
int a[15][15]; ///数独面板
int f[15];
int tm = 1; ///带?的个数+1
vector<int> v[15];
int flag = 0; ///结束标志
wh q[100]; /// '?' 节点存储
int getfg(int x,int y){ ///获取坐标所在的3X3方格位置
return ((x-1)/3)*3+((y-1)/3+1);
}
int getzb(int t){
int xx=(t)/3*3+1;
int yy=(t+1)%3-1;
printf("%d %d\n",xx,yy);
return 0;
}
bool isok9(int x,int y,int ans){ ///3X3小方格或行或列符合规则吗
for(int i = 1; i <= 9; ++i)
if(a[i][y] == ans)
return false;
for(int i = 1; i <= 9; ++i)
if(a[x][i] == ans)
return false;
//int tmp = getfg(x,y);
int xx=(x-1)/3*3+1;
int yy=(y-1)/3*3+1;
for(int i = xx; i < xx+3; ++i){
for(int j = yy; j < yy+3; ++j){
if(a[i][j] == ans) return false;
}
}
return true;
}
void print(){ ///打印结果
for(int i = 1; i <= 9; ++i){
printf("%d",a[i][1]);
for(int j = 2; j <= 9; ++j){
printf(" %d",a[i][j]);
}
printf("\n");
}
//printf("\n");
}
void printv(){
for(int i = 1; i <= 9; ++i){
printf("%d: ",i);
for(int j = 0; j < (int)v[i].size(); ++j){
printf("%d ",v[i].at(j));
}
printf("\n");
}
}
void printwh(){
for(int i = 1; i < tm; ++i){
printf("%d %d : %d\n",q[i].x,q[i].y,getfg(q[i].x,q[i].y));
}
}
void dfs(int t){
if(t == tm){ ///搜到最后一个点结束
flag = 1;
return;
}
int x = q[t].x;
int y = q[t].y;
//for(int i = 0; i < (int)v[tmp].size(); ++i){
for(int i = 1; i <= 9; ++i){
if(isok9(x,y,i)){
a[x][y] = i;
dfs(t+1);
if(flag) return;
a[x][y] = 0;
}
}
}
int main(int argc, char *argv[]) {
int k = 1;
char str[2];
while(~scanf("%s",str)){
getchar();
tm = 1;
flag = 0;
//memset(book,0,sizeof(book));
memset(f,0,sizeof(f));
for(int i = 1; i <= 9; ++i) v[i].clear();
if(str[0] != '?') a[1][1] = str[0] - '0';
else{
q[tm].x = 1;
q[tm++].y = 1;
a[1][1] = 0;
}
for(int i = 1; i <= 9; ++i){
for(int j = 1; j <= 9; ++j){
if(i == 1 && j == 1) continue;
scanf("%s",str);
if(str[0] != '?') a[i][j] = (str[0]-'0');
else{
q[tm].x = i;
q[tm++].y = j;
a[i][j] = 0;
}
}
}
for(int i = 1; i <= 9; i += 3){
for(int j = 1; j <= 9; j += 3){
memset(f,0,sizeof(f));
for(int k = i; k < i+3; ++k){
for(int l = j; l < j+3; ++l){
f[a[k][l]] = 1;
}
}
int t = getfg(i,j);
for(int k1 = 1; k1 <= 9; ++k1)
if(f[k1] == 0) v[t].push_back(k1);
}
}
dfs(1);
if(k == 1){
print();
k++;
}
else{
printf("\n");
print();
}
}
return 0;
}