题意:给定一个未完成的数独,0是待填位置,其他均为已填入的数字.如果能将其
补充完整,则输出补充完整的数独(有多组答案输出任意一组),否则原样输出
数独:一个9行9列的网格,包括9个3*3的子网格,要求每行、每列、每个子网格内
都只能使用一次1-9中的一个数字,
即每行、每列、每个子网格内都不允许出现相同的数字。
分析:对于每一个未填的格,依次判断它所在行、列、子网格是否填了1-9,
若都未填,先填上该值,继续搜索,
若无法填写了,再回溯,填上其他可能的值,继续搜索
看别人博客说饭搜比正搜快很多
试了下反搜,32MS,(代码如下),改成正搜,1532MS,不明觉厉,但不知道为什么
#include<stdio.h> #include<string.h> int map[10][10]; struct stu { int x,y; }gird[100]; int judge(int x,int y,int k) { int i,j,c,r; for(i=0;i<9;i++) //判断所在行、列是否填了k值 if(map[i][y]==k||map[x][i]==k) return 0; r=x/3*3; //计算子网格的行列号 c=y/3*3; for(i=r;i<r+3;i++) //判断所在子网格是否填了k for(j=c;j<c+3;j++) if(map[i][j]==k) return 0; return 1; } int dfs(int pos) { int i,x,y; if(pos<0) return 1; for(i=1;i<=9;i++){ x=gird[pos].x; y=gird[pos].y; if(judge(x,y,i)){ //判断是否能填i map[x][y]=i; if(dfs(pos-1)) return 1; map[x][y]=0; //回溯 } } return 0; } int main() { int i,j,T,num; char c; scanf("%d",&T); getchar(); while(T--){ num=0; for(i=0;i<9;i++){ for(j=0;j<9;j++){ scanf("%c",&c); map[i][j]=c-'0'; if(c=='0'){ //记录未填写的格的行列号 gird[num].x=i; gird[num++].y=j; } } getchar(); } dfs(num-1); //从最后一个未填写的格反搜 for(i=0;i<9;i++){ for(j=0;j<9;j++) printf("%d",map[i][j]); printf("\n"); } } return 0; }
时间: 2024-10-02 21:20:18