hdu - 数独问题

来源:互联网 发布:linux进程数据结构 编辑:程序博客网 时间:2024/05/16 18:37

警告:  qdu14级信安同学请不要复制此代码,要不然会被查重……


E - 数独问题
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit Status

Description

自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视。 
据说,在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 29 2 4 ? 5 6 ? 3 75 ? 6 ? ? ? 2 4 11 ? 3 7 2 ? 9 ? 5? ? 1 9 7 5 4 8 66 ? 7 8 3 ? 5 1 98 5 9 ? 4 ? ? 2 3

Sample Output

7 1 2 4 6 9 3 5 83 6 5 2 8 7 1 9 44 9 8 5 1 3 6 7 29 2 4 1 5 6 8 3 75 7 6 3 9 8 2 4 11 8 3 7 2 4 9 6 52 3 1 9 7 5 4 8 66 4 7 8 3 2 5 1 98 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;        ///带?的个数+1vector<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;}




0 0
原创粉丝点击