HDU 1426 Sudoku Killer

来源:互联网 发布:正大数据恢复乱开价 编辑:程序博客网 时间:2024/06/05 17:34

此题输入格式十分奇怪,用scanf("%s",s );来收下每个字符就能忽略空格的影响了。

思路是简单DFS,把每个为问号的点存下来进行DFS枚举,枚举时判断下能否放入该数字然后回溯结果即可。

附渣代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <memory.h>#include <queue>#define MAX 82using namespace std;struct node{    int i,j;}ans[MAX],sudu[3][3];int cs,flag;char map[10][10];void printmap(){    int i,j;    for(i=0;i<9;i++){            for(j=0;j<9;j++){                printf(j==8?"%c\n":"%c ",map[i][j]);            }        }}bool judge(int p,int x)//判断改点为x是否可行{    int row=ans[p].i,cl=ans[p].j;    int i,j;    for(i=0;i<9;i++){        if((map[row][i]!='?')&&(map[row][i]-'0'==x))//行        return 0;        if((map[i][cl]!='?')&&(map[i][cl]-'0'==x))//列        return 0;    }    i=ans[p].i/3;      //计算改点所在小方块的位置    j=ans[p].j/3;    row=sudu[i][j].i;    cl=sudu[i][j].j;    for(i=row;i<row+3;i++){        for(j=cl;j<cl+3;j++){            if((map[i][j]!='?')&&(map[i][j]-'0'==x))            return 0;        }    }    return 1;}void dfs(int nodei){    if(flag)return;    if(nodei==cs){        flag=1;        printmap();    }    int i;    for(i=1;i<=9;i++){        if(!judge(nodei,i))            continue;        char c;        c=map[ans[nodei].i][ans[nodei].j];        map[ans[nodei].i][ans[nodei].j]=i+'0';//设置回溯        dfs(nodei+1);        if(flag)        return ;        map[ans[nodei].i][ans[nodei].j]=c;//回溯    }}int main(){    sudu[0][0].i=0;sudu[0][0].j=0;    sudu[0][1].i=0;sudu[0][1].j=3;    sudu[0][2].i=0;sudu[0][2].j=6;    sudu[1][0].i=3;sudu[1][0].j=0;    sudu[1][1].i=3;sudu[1][1].j=3;    sudu[1][2].i=3;sudu[1][2].j=6;    sudu[2][0].i=6;sudu[2][0].j=0;    sudu[2][1].i=6;sudu[2][1].j=3;    sudu[2][2].i=6;sudu[2][2].j=6;//存放数独9个小方块的左上角坐标    int i,j;    char s[10];    int casi=0;    while(scanf("%s",s)!=EOF){        if(casi!=0)        printf("\n");//输出格式:每个CASE间有空行,结尾没有空行。        casi++;        cs=0;        map[0][0]=s[0];        if(map[0][0]=='?'){            ans[cs].i=0;            ans[cs].j=0;            cs++;        }        for(i=0;i<9;i++){            if(i==0)j=1;            else j=0;            for(;j<9;j++){                scanf("%s",s);      //用字符串输入,每次取s[0]                map[i][j]=s[0];                if(map[i][j]=='?'){                    ans[cs].i=i;                    ans[cs++].j=j;                }            }        }        flag=0;        dfs(0);    }    return 0;}
其实可以用来解所有数独。。。只是因为是根据问号数目进行递归,要是问号过多或者DFS树需要的节点很多就可能很慢甚至超栈。。。

原创粉丝点击