HDU1426 Sudoku Killer(DFS 选对搜索对象很重要)

题意:给一个没有完成的数独,输出完整结果。数据保证有且只有一个解。


思路:题意明确,思路还是比较好想的,找到每个空的位置,把1到9尝试一遍只要不冲突就填上再往下搜索一直找到解就行了。

卡在两个地方:

1、题目的格式要求。多组输入,输入数据之间有空行,输出的解之间也要有空行。为了解决数据之间的空格,特意搞了一段特盼,为此还WA了两发,后来想起来scanf是自动忽略回车的!所以不需要处理。唉,又是智障错误卡。。。

2、最初选取的搜索对象是每个位置,找到从这个位置开始的第一个空位置,TLE到吐。。。然而怎么都找不出问题,参考了网上的解法,发现都是记录下每个“?”的位置,直接按顺序搜索这些位置就行了,尝试了一下,很快就A了!

关于第二个问题,还是感觉两种方法时间并不会差很大,应该是代码实现问题?这个问题留着,以后再来尝试。


#include<bits/stdc++.h>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF  0x3f3f3f3f
typedef long long  LL;
typedef pair<int,int> P;
P node[90];
int sd[10][10],f=0,cnt;
bool jud(int x,int y,int k){
    for(int i=0;i<9;++i){//判断行和列
        if(sd[i][y]==k)return false;
        if(sd[x][i]==k)return false;
    }
    int tmpx=(x/3)*3,tmpy=(y/3)*3;
    for(int i=tmpx;i<tmpx+3;++i){//判断九宫格
        for(int j=tmpy;j<tmpy+3;++j){
            if(sd[i][j]==k)return false;
        }
    }
    return true;
}
void dfs(int n){
    if(f)return;
    if(n==cnt){
        f=1;
        for(int i=0;i<9;++i){
            for(int j=0;j<9;++j){
                printf("%d%c",sd[i][j],j==8?'\n':' ');
            }
        }
        return;
    }
    for(int i=1;i<=9;++i){
        if(jud(node[n].first,node[n].second,i)){
            sd[node[n].first][node[n].second]=i;
            dfs(n+1);
        }
        if(f)return;//找到结果,退出函数
    }
    sd[node[n].first][node[n].second]=0;//循环结束也没有解,说明此状态无解,退回0
}
int main(){
    char s[5];
    int i,j;
    while(~scanf("%s",s)){//scanf自动忽略回车,所以不用处理数据之间的空行
        cnt=0;
        sd[0][0]=(s[0]=='?'?0:s[0]-'0');//处理第一行第一位
        for(i=1;i<9;++i){
            scanf("%s",s);
            sd[0][i]=(s[0]=='?'?0:s[0]-'0');//第一行后面八位
        }
        for(i=1;i<9;++i){
            for(j=0;j<9;++j){
                scanf("%s",s);
                sd[i][j]=(s[0]=='?'?0:s[0]-'0');//后面八行
            }
        }
        for(int i=0;i<9;++i){//记录没有填的位置
            for(int j=0;j<9;++j){
                if(!sd[i][j])node[cnt].first=i,node[cnt++].second=j;
            }
        }
        if(f)putchar('\n');//两组解之间有空格
        f=0;
        dfs(0);
    }
}


猜你喜欢

转载自blog.csdn.net/hcx11333/article/details/54674951