您的位置:首页 > 其它

DFS求解数独算法

2018-09-25 21:22 127 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LittleWhiteLv/article/details/82845364

        以前也想过很久解数独的算法,但是没有得到很简单的方法,某天看到某位学长的代码,恍然大悟,本以为暴力搜索会很花时间(10^81种可能),没想到实际上由于各种限制,枚举次数竟然普遍小于10000次,用dfs便可实现每种可能都列举。这样计算一个数独就很快了(不到1ms),下面附上自己理解改动并加了注释的代码,DEV编译可能会效果好一些。

代码:

[code]#include <stdio.h>
#include<stdlib.h>
#include<windows.h>
char map[9][9],xx;
int ans=0;
bool suit=false;
void position(int x,int y) {
COORD pos={x,y};
HANDLE Out=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(Out,pos);
}
void Hide() {
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle,&CursorInfo);		//获取控制台光标信息
CursorInfo.bVisible = false;		//隐藏控制台光标
SetConsoleCursorInfo(handle,&CursorInfo);		//设置控制台光标状态
}
void print(int x,int y) {
ans++;
position(y*2,x);
printf("%d",map[x][y]);
position(0,11);
printf("\n已尝试:%d次\n",ans);
}
bool check(int n,int v) {
int x=n%9;
int y=n/9;
for(int i=0;i<9;i++) if(map[x][i]==v||map[i][y]==v) return false;	//检验横竖
x=x/3*3;
y=y/3*3;
for(int i=x;i<x+3;i++) for(int j=y;j<y+3;j++) if(map[i][j]==v) return false;	//检验九宫格
return true;
}
void dfs(int n) {	//暴力查找
int x=n%9;
int y=n/9;
if (n==81||suit) {	//出口
suit=true;
return;
}
if (map[x][y]!=0) dfs(n+1);
else for(int i=1;i<=9;i++) if(check(n,i)) {
map[x][y]=i;
print(x,y);
dfs(n+1);
if(suit) return;
map[x][y]=0;
}
}
int main() {
int i,j;
freopen("1.txt","r",stdin);	//从文档读入
Hide();		//隐藏光标
for (i=0;i<9;i++) {
for (j=0;j<9;j++) {
scanf("%c",&map[i][j]);
map[i][j]-='0';
}
if(i!=8||j!=8) scanf("%c",&xx);	//读换行
}
for(i=0;i<9;i++) {		//初始化屏幕
for(j=0;j<9;j++) printf("%d ",map[i][j]);
printf("\n");
}
position(25,5);
printf("正在求解数独。。。");
dfs(0);
printf("\n求解完毕!\n");
}

效果图:

 还可以再加一个求出所有解的动能。

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: