深搜玩转数独

数独是十分流行的智力游戏 但用深搜(DFS),可以轻松解决这个问题。

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

int map[9][9],vis[10][10],a[10][10],b[10][10];

int count_num,flag;  //count表示0的个数

struct node

{

int x;

int y;

}num[82];

void dfs(int k)

{

if(k==count_num)  //填满输出

{

printf("\n");

flag=1;

for(int i=0;i<9;i++)

{

for(int j=0;j<9;j++)

printf("%d ",map[i][j]);

printf("\n");

}

printf("\n");

return;

}

for(int i=1;i<10;i++)  //从1-9选一个数填

{

///vis[i/3*3+j/3][map[i][j]]=1;

if(!vis[num[k].x/3*3 + num[k].y/3][i] && !a[num[k].x][i] && !b[i][num[k].y])  //判断每个九宫格里有没有这个数   //行列都没有这个数

{

map[num[k].x][num[k].y]=i; //填上这个数

vis[num[k].x/3*3+num[k].y/3][i]=1;////////

a[num[k].x][i]=1;

b[i][num[k].y]=1;

dfs(k+1);

//if(flag)  //已完成任务 返回

//return;

map[num[k].x][num[k].y]=0;//不符合 去了这个数

vis[num[k].x/3*3+num[k].y/3][i]=0;/////归零

a[num[k].x][i]=0;   //归零

b[i][num[k].y]=0;

}

}

return;

}

int main()

{

int k=1;

while(k)

{

flag=0;

cout<<"请输入数独形式:\n";

memset(vis,0,sizeof(vis));  //二维清空数组

memset(a,0,sizeof(a));

memset(b,0,sizeof(b));

count_num=0;

flag=0;

for(int i=0;i<9;i++)

for(int j=0;j<9;j++)

{

scanf("%d",&map[i][j]);

if(map[i][j])

{

vis[i/3*3+j/3][map[i][j]]=1;  //其所在的九宫格里有这个数

a[i][map[i][j]]=1;  //该行有这个数

b[map[i][j]][j]=1;  //该列有这个数

}

else

{

num[count_num].x=i;

num[count_num++].y=j;   //记下空格坐标

}

}

cout<<"答案为:\n";

dfs(0);

if(!flag) cout<<"无答案!"<<endl;

}

return 0;

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-30 17:13:54

深搜玩转数独的相关文章

[NOIP2009]靶形数独 深搜+枝杈优化

这道题,又是一位玄学搜索...... 我是用的蜗牛序搜的(顾名思义,@,这么搜),我正着搜80然后一反转比原来快了几十倍........一下AC....... 我的思路是这样的话我们可以从内到外或者从外到内搜索,这样的话我们就可以在一定程度上运用贪心,因为中间的价值大外面的价值小,我是作为一个从来没有玩过数独的人的思路...然而任何一个玩过数独的人都会先选可能状态少的优先搜索....... 对于这题里的数据,可行方案很少因此摆在我们面前的不是减去不优的解而是减去不成立的解,然而对于不成立的解在我

洛谷 P1019 单词接龙 深搜

题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在"龙"中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输出格式 输入格式: 输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每

hdu 1342 记忆化深搜

Lotto Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1657    Accepted Submission(s): 811 Problem Description In a Lotto I have ever played, one has to select 6 numbers from the set {1,2,...,49

深搜整理汇总

2801 LOL-盖伦的蹲草计划 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题目描述 Description 众所周知,LOL这款伟大的游戏,有个叫盖伦的英雄.他的伟大之处在于他特别喜欢蹲草丛阴人(XL:蹲草阴人也算英雄?!CZQ:没办法,个个都是这么玩的).某日,德玛西亚与诺克萨斯之间又发生了一场战斗,嘉文四世希望盖伦能带领一支K人的德玛西亚军队出战. 战斗发生在召唤师峡谷.整个召唤师峡谷被分割成M行N列的一个矩阵,矩阵中有空地和几片草丛.这几片草丛中有

fzu 1920 Left Mouse Button(简单深搜题)

题目地址:http://acm.fzu.edu.cn/problem.php?pid=1920 题目大意是给定一个n*n的图,模拟扫雷游戏,0代表没有雷区,1代表附近九宫格内只有一个雷-- 如果不懂的话去玩下扫雷,挺好玩的,99个雷的玩了好几百盘才赢了一次............ 此题假设神操作,点不到雷,问你最少要多少下才可以把图中非雷的点完,怎么样才最快呢? 当然先点0啦,,,,,,,, 好吧,不废话了..... ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1

(暴力+深搜)POJ - 2718 Smallest Difference

原题链接: http://poj.org/problem?id=2718 题意: 给你几个数字,可以分成两个子集,然后分别按一定顺序排列组成一个数,求出这两只值差的绝对值的最小值. 分析: 反正也是刷着玩,果断先交一波全排列枚举的代码,果断TLE,然后开始想正解. 稍微想想,既然要差最小,肯定是两个数各一半.所以只要深搜出所有n/2(n为给定数字的个数)的组合,另外个n-n/2个数就有了. 但是枚举出来后的操作又想了很久,想过很多算法,都不怎么满意,最终用二分解决. 先把n/2和n-n/2全排列

【日常学习】【深搜】codevs2452 扫雷题解

题目来源:05年四川省选 转载请注明出处 [ametake版权所有]http://blog.csdn.net/ametake欢迎来看 题目描述 Description 相信大家都玩过扫雷的游戏.那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来.万圣节到了,"余"人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字表示和它8连通的格子里面雷的数目.现在棋盘是n×2的,第一列里面某些格子是雷,而第二列没有雷, 由于第一列的雷可能有多种方案

7.23 深搜广搜

深搜(DFS)  关键词:回溯 栈实现,(递归本质和栈一样)一直走到底再回溯,时间复杂度高,空间低 #include<iostream> #include<cstring> using namespace std; int R,C; char maps[40][40]; int dp[40][40]; int dir[2][4]={{1,0,0,-1},{0,1,-1,0}}; int ans=1<<30; void DFS(int x,int y,int step){

hdu1455 Sticks 深搜 强剪枝

Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6035    Accepted Submission(s): 1704 Problem Description George took sticks of the same length and cut them randomly until all parts becam