24年1.29深搜

本文介绍了深度优先搜索算法在全排列、最短路径和自然数拆分问题中的应用,展示了如何通过递归实现这些计算机科学中的经典问题解决方案。
摘要由CSDN通过智能技术生成
  • 定义
  • 全排列
  • 最短路径
  • 自然数的拆分
  • 高手散步

定义(不撞南墙不回头)

深度优先搜索(Depth-First Search,DFS)是十分常见的图搜索方法之一。深度优先搜索会沿着一条路径一直搜索下去,在无法搜索时,回退到刚刚访问过的节点。(一条路走到黑

全排列

#include<stdio.h>
int n;//数字 
int a[10]; 
int book[10];//标记 
void dfs(int step){
	if(step==n+1){
	  for(int i=1;i<=n;i++){
	  	printf("%d ",a[i]);
	  }
	  printf("\n");
	  return;//返回上一步
	}
	for(int i=1;i<=n;i++)//尝试每种可能 
	{
		if(book[i]=0)//如果这个牌在手上 
		{
			a[step]=i;//step号箱子被放入i 
			book[i]=1;//i牌被标记 
			dfs(step+1);//去下一个箱子 
			book[i]=0;
		}
	}
	return; 
}
int main(){
	
	scanf("%d",%n);
	dfs(1);
} 

最短路径

#include<stdio.h>
int n,m;
int startx,starty,p,q;
int book[20][20],a[20][20];
int min=9999999;
void dfs(int step,int x,int y){
	if(x==p&&y==q){
		if(step<min)//到达终点 
		{
			min=step;
		}
		return ;
	}
	int next[4][2]={{0,1},//向右走 
                	{1,0},//向下走 
                	{0,-1},//向左走 
                 	{-1,0}//向上走 
                        	};
	int tx,ty,k;
	for(k=0;k<=3;k++)//每一种尝试 
	{
	
		tx=x+next[k][0];
		ty=y+next[k][1];//此时的位置 
		if(tx<1||ty<1||tx>n||ty>m)//如果走出边界 
		   continue;
	
	if(a[tx][ty]==0&&book[tx][ty]==0)//这点没有障碍并且没有被标记 
	{
		  book[tx][ty]=1;//标记这点 
		  dfs(step+1,tx,ty);//下一步 
		  book[tx][ty]=0;//返回时取消标记 
	}
}
	
}
int main(){
	
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%d",&a[i][j]);
		}
	}
	scanf("%d %d %d %d",&startx,&starty,&p,&q);

	book[startx][starty]=1;// 第一个位置标记掉

	dfs(0,startx,starty);

	printf("%d",min);
	
} 

自然数的拆分

#include<stdio.h>
int a[10001]={1};
int n;//数字 
void fff(int m,int t)//t是分成数字的个数(箱子数) m是剩余字的大小 
{
	int i;int k;
	for(i=a[t-1];i<=m;i++)//当前数要比前面一个树大所以i从a[t-1]开始 
	{
		if(i<n){
			a[t]=i;//箱子中放
			m-=i;//减去后还剩下的
			if(m==0){
				printf("%d",a[1]); 
				for(k=2;k<=t;k++){
					printf("+");
					printf("%d",a[k]);
				}
				printf("\n");
			}
			else{
				fff(m,t+1);
					m+=i;//回溯
			} 
		
		}
	} 
	
	
} 

int main() 
{
	scanf("%d",&n);
	fff(n,1); 
	
	
}



高手去散步


#include<stdio.h>
int d[23][23];
int x,y,f;
int book[23];//标记走过的景点 
int n,max=0;//n为景点总数 
void dfs(int k,int sum,int p)//走过的景点数 k和当前走过的距离sum 和当前的位置 
{
	int i;
	if(sum>max)max=sum;
	if(k==n) return ;//全部走完了  返回 换一条路
	for( i=1;i<=n;i++){
		if(d[p][i]>0&&book[i]==0)//当前位置能到i并且i位置未被标记
		{
			sum+=d[p][i];

			book[i]=1;

			dfs(k++,sum,i);//找下一条路

			book[i]=0;//接触标记

			sum-=d[p][i];
		} 
	}
	
 } 

int main()
{
	int m;int i;
	scanf("%d %d",&n,&m);
	for( i=1;i<=m;i++){
		scanf("%d %d %d",&x,&y,&f);
		d[x][y]=f;
		d[y][x]=f;//双向路 
	}
	for(i=1;i<=n;i++)//尝试不同的起点 
	{
		    book[i]=1;//标记
        	dfs(1,0,i);
        	book[i]=0;//回溯 
       
	
	}
	printf("%d",max); 
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值