dfs深度优先搜索算法相关三类问题与解

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


什么是dfs算法

提示:这里可以添加本文要记录的大概内容:

深度优先搜索算法(Depth First Search,简称DFS):⼀种⽤于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可
能深的搜索树的分⽀。当节点v的所在边都⼰被探寻过或者在搜寻时结点不满⾜条件,搜索将回溯到发现节点v的那条边的起始节点。
整个进程反复进⾏直到所有节点都被访问为⽌。属于盲⽬搜索,最糟糕的情况算法时间复杂度为O(!n)。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Fibonacci数列问题

//开胃小菜
#include<bits/stdc++.h>
using namespace std;
int fib(int n)
{
	if(n==1 || n==2) return 1;
	int m=fib(n-1)+fib(n-2);
	return m;
}
int main()
{
	int n;
	scanf("%d",&n);
	printf("%d\n",fib(n));
	return 0;
}

二、八皇后问题+数独问题(简略版)

在作者另一篇文章中有针对java语言的更为一般的八皇后问题解法

#include<bits/stdc++.h>
using namespace std;
#define N 15 
int ans[N],cnt=0,n,lie[N],dui[105],du[2*N],fl=0;
void work()
{
	cnt++;
	if(cnt>3) return;
	for(int i=1;i<=n;++i) printf("%d ",ans[i]);
	printf("\n");
}
int get(int x)
{
	if(x<0) return x+100;
	return x;
}
void dfs(int now)
{
	if(now==n+1) {   work(); return; }
	for(int i=1;i<=n;++i)
	if( !lie[i] && !dui[get(now-i)] && !du[now+i]){
		lie[i]=1; dui[get(now-i)]=1; du[now+i]=1;
		ans[now]=i;
		//printf("now:%d i:%d\n",now,i);
		dfs(now+1);
		ans[now]=0;
		lie[i]=0; dui[get(now-i)]=0; du[now+i]=0;
	}
}
int main()
{
	scanf("%d",&n);
	dfs(1);
	printf("%d\n",cnt);
}


//数独问题(简略版)


#include<bits/stdc++.h>
using namespace std;
#define N 15
int ans[N][N],ge[N][N],shu[N][N],he[N][N],a[N][N];
void work()
{
	for(int i=1;i<=9;++i){
		for(int j=1;j<=9;++j)
	  	printf("%d ",ans[i][j]);
	  	cout<<endl; 
	}
}
void dfs(int i,int j)
{
	if(i==9 && j==10) { work(); return ;}
	if(j==10)  { dfs(i+1,1); return ; }
	if(ans[i][j]) { dfs(i,j+1); return ; }
	for(int ii=1;ii<=9;ii++)
	if(!he[i][ii] && !shu[j][ii] && !ge[(i-1)/3*3+(j-1)/3+1][ii]){
		he[i][ii]=1, shu[j][ii]=1, ge[(i-1)/3*3+(j-1)/3+1][ii]=1;
		ans[i][j]=ii;
		dfs(i,j+1);
		he[i][ii]=0, shu[j][ii]=0, ge[(i-1)/3*3+(j-1)/3+1][ii]=0;
		ans[i][j]=0;
	}
}
int main()
{
	for(int i=1;i<=9;++i){
		for(int j=1;j<=9;++j){
			scanf("%d",&a[i][j]);
			if(a[i][j])
			he[i][a[i][j]]=1, shu[j][a[i][j]]=1, ge[(i-1)/3*3+(j-1)/3+1][a[i][j]]=1;
			//if(!a[i][j]) fl[0][i]|=(1<<(9-j));
			ans[i][j]=a[i][j];
		}
	}
	dfs(1,1);
	//for(int i=1;i<=9;++i)
	// for(int j=1;j<=9;++j)
	 // if(!a[j][i]) fl[1][i]|=(1<<(9-j));
	 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值