深搜全排列

最基础的深搜全排列

#include <bits/stdc++.h>
using namespace std;
int n, a[10];
bool vis[10];
//准备给第cnt个位置安排数字 
void dfs(int cnt)
{
	//准备给第n+1个位置安排数的时候, 说明前n个位置都安排好了
	if(cnt==n+1){	 
		for(int i=1; i<=n; ++i){
			printf("%5d", a[i]);
		} 
		printf("\n");
		return;
	}
	//准备给第cnt个位置安排 
	for(int i=1; i<=n; ++i){
		if(!vis[i]){	//i这个数没被前面的位置使用 
			a[cnt]=i; 
			vis[i]=true;
			dfs(cnt+1);
			vis[i]=false;
		}
	} 
} 
int main()
{
	scanf("%d", &n);  
	dfs(1);		//准备给第一个位置安排数字 
	return 0;
} 

#include <bits/stdc++.h>
using namespace std;
int n, a[10006], total;
bool vis[1006];
//当前是填第几个数 
void dfs(int cnt)
{
	if(cnt==n+1){
		for(int i=1; i<=n; ++i){
			printf("%d ", a[i]);
		}
		printf("\n");
		total++;
		return;
	} 
	for(int i=1; i<=n; ++i){
		if(vis[i]==false){
			vis[i]=true;
			a[cnt]=i;
			dfs(cnt+1);
			vis[i]=false;
		}
	}
}
int main()
{
	scanf("%d", &n); 
	for(int i=1; i<=n; ++i){
		vis[i]=true;
		a[1]=i;
		dfs(2);
		vis[i]=false;
	}
	printf("%d", total);
	return 0;
} 

用next_permutation(a+1, a+n+1);函数

#include <bits/stdc++.h>
using namespace std;
int n, a[10], tot=1;
int main()
{
	scanf("%d", &n);
	for(int i=1; i<=n; ++i){
		tot*=i;
		a[i]=n+1-i;
	}	 
	while(tot--){
		next_permutation(a+1, a+n+1);
		for(int i=1; i<=n; ++i){
			printf("%5d", a[i]);
		}
		printf("\n");
	} 
	return 0;
}

P1088 [NOIP2004 普及组] 火星人

基于某个排列状态,找出其后面第m个全排列

//搜索和排列的一道好题 
//基于当前的start[i]这一状态, 继续往后找m个全排列 
#include <bits/stdc++.h>
using namespace std;
int n, m, a[10006], start[10006], total=-1;	//因为初始状态会再找一遍, 所以total初始化为-1 
bool vis[10006];
//基于当前的start[i]这一状态, 继续往后找m个全排列 
//当前是填第几个数 
void dfs(int cnt)
{
	if(cnt==n+1){	//n个数全部排列完了 
		total++;	//方案数++ 
		if(total==m){	//当前找到的为初始状态后面的第m个排列
			for(int i=1; i<=n; ++i){
				printf("%d ", a[i]);
			}	
			exit(0);	//结束程序 
		} 
		return;
	}
	//flag为false表示前cnt-1位均未发生改变, 仍为start[]初始状态 
	bool flag=false;
	for(int i=1; i<=cnt-1; ++i){
		if(a[i]!=start[i]){	//只要前面有发生改变的, 就置为true 
			flag=true;
		}
	}
	if(flag==false){	//前面的位数都没变, 这一位只能从start[cnt]变到n 
		for(int i=start[cnt]; i<=n; ++i){
			if(vis[i]==false){
				vis[i]=true;
				a[cnt]=i;
				dfs(cnt+1);
				vis[i]=false;
			}
		}	
	}
	else{	//前面的位数有改变, 这一位可以取1~n, 只要vis[]满足前面没取过即可 
		for(int i=1; i<=n; ++i){
			if(vis[i]==false){
				vis[i]=true;
				a[cnt]=i;
				dfs(cnt+1);
				vis[i]=false;
			}
		}
	}
}
int main()
{
	scanf("%d", &n);
	scanf("%d", &m);
	for(int i=1; i<=n; ++i){
		scanf("%d", &start[i]);
	}
	//a[1]可能的取值范围为: start[1]~n, 基于a[1]去搜索a[2~n] 
	for(int i=start[1]; i<=n; ++i){
		vis[i]=true;
		a[1]=i;
		dfs(2);
		vis[i]=false;
	}
	return 0;
}

方法二:直接调用next_permutation(a+1, a+n+1)函数来计算全排列

//搜索和排列的一道好题 
//基于当前的start[i]这一状态, 继续往后找m个全排列 
//调用库函数 
#include <bits/stdc++.h>
using namespace std;
int n, m, a[10006];
int main()
{
	scanf("%d", &n);
	scanf("%d", &m);
	for(int i=1; i<=n; ++i){
		scanf("%d", &a[i]);
	}
	while(m--){
		next_permutation(a+1, a+n+1);
	} 
	for(int i=1; i<=n; ++i){
		printf("%d ", a[i]);
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ypeijasd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值