0
点赞
收藏
分享

微信扫一扫

★递归递推★

简单聊育儿 2022-04-04 阅读 70
算法dfs

---------------------------------------------------------------------------------------------------------------------------------

 

目录

92-递归实现指数型枚举

94-递归实现组合型枚举

1209-带分数


92-递归实现指数型枚举

题目:

从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。

输入格式:

输入一个整数 n。

输出格式:

每行输出一种方案。

同一行内的数必须升序排列,相邻两个数用恰好 11 个空格隔开。

对于没有选任何数的方案,输出空行。

本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。

数据范围:

1≤n≤15

输入样例:

3

 输出样例:


3
2
2 3
1
1 3
1 2
1 2 3

分析: 

代码: 

#include<iostream>
using namespace std;

const int N=20;
bool state[N];
int num[N];
int n;

void dfs(int u)
{
	if(u>n)
	{
		for(int i=1;i<=n;i++)
			if(state[i]==1)
				cout<<i<<" ";
		cout<<endl;
		
		return;
	}
	
	
	//不同行升序--先选 
//	//先选
//	state[u]=true;
//	dfs(u+1);
//	//恢复现场+不选 
//	state[u]=false;
//	dfs(u+1);
	
	//不同行不升序--先不选
	//先不选
	state[u]=false;
	dfs(u+1);
	//选 
	state[u]=true;
	dfs(u+1); 
	
}

int main()
{
	cin>>n;
	
	dfs(1);
	
	
	return 0;
}

---------------------------------------------------------------------------------------------------------------------------------

94-递归实现组合型枚举

题目详情:

分析: 

代码 

//4.4重做 
#include<iostream>
using namespace std;

const int N=20;
int num[N];
int n,m;
int flag;

void dfs(int u,int state)
{
	if(u>m)
	{
		for(int i=1;i<=m;i++)
			cout<<num[i]<<" ";
		cout<<endl;
		
		return ;
	}
	
	for(int i=state;i<=n;i++)
	{
		num[u]=i;
		dfs(u+1,i+1);
	}
}

int main()
{
	cin>>n>>m;
	
	dfs(1,1);
	
	return 0;
}

另一种解法代码(不设置状态数):

分析

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int N=110;
int n,m;
int flag=0;
int p[N];

void dfs(int u)
{
	//边界条件-当存储的数为m时
	if(flag==m)
	{
		for(int j=1;j<=flag;j++)
			cout<<p[j]<<" ";
			
		cout<<endl;	
		return ;
	} 
	//深搜	
	for(int i=u;i<=n;i++)
	{
		p[++flag]=i;	
		dfs(i+1);
		p[flag--]=0;//或者直接写成 flag--; 一次递归结束后恢复数据
	}
	
}
int main()
{
	scanf("%d%d",&n,&m);
	
	dfs(1);
	
	return 0;
} 

---------------------------------------------------------------------------------------------------------------------------------

1209-带分数

题目详情:

分析:

 代码:

#include<iostream>
#include<algorithm> 
using namespace std;

const int N=1e6+10;
int n;			    //需要求的目标数
int num[10];        //存放全排列的结果
bool st[10];        //全排列记录数是否被用过
int res=0;          //最终结果

int arr(int l,int r)
{
	int ans=0;//划分好的答案
	for(int i=l;i<=r;i++)
	{
		ans=ans*10+num[i];
	} 
	return ans;
	
} 

void dfs(int u)
{
	if(u>9)
	{
        //暴力将每个数划分为三段
		for(int i=1;i<=7;i++)
			for(int j=i+1;j<=8;j++)
			{
				int a=arr(1,i);
				int b=arr(i+1,j);
				int c=arr(j+1,9);
				
			    //满足题设条件
				if(n*c==a*c+b)
				{
					res++;
				}
			}
			
			return ;
	}
	
	//对数进行全排列 
	for(int i=1;i<=9;i++)
	{
		if(!st[i])
		{
			st[i]=true;
			num[u]=i;
			dfs(u+1);
			st[i]=false;
		}
	}
}

int main()
{
	cin>>n;
	
	dfs(1);
	
	cout<<res;
	
	return 0;
}
 

另一种解法:

next_permutation用法链接https://www.cnblogs.com/kingwz/p/15187020.html

代码: 

//函数全排列
#include<iostream>
#include<algorithm>
using namespace std;

int n;
int num[10];
int ans=0;

int calt(int l,int r)
{
	int res=0;
	for(int i=l;i<=r;i++)
	{
		res=res*10+num[i];
	}
	
	return res;
}

int main()
{
	cin>>n;
	for(int i=1;i<=9;i++)	num[i]=i;
	do{
		for(int i=1;i<8;i++)
			for(int j=i+1;j<9;j++)
			{
				int a=calt(1,i);
				int b=calt(i+1,j);
				int c=calt(j+1,9);
				
				if(a*n==b*a+c) ans++;
			}
	}while(next_permutation(num+1,num+10));
	
	cout<<ans;
} 
举报

相关推荐

0 条评论