全排列——模拟全排列

**题目:**https://www.luogu.org/problemnew/show/P1088
题解:
方法一:直接调用next_permutation

#include <bits/stdc++.h>
using namespace std;
int n,m,a[10005];
int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++) cin>>a[i];
	while(m--) next_permutation(a,a+n);
	for(int i=0;i<n;i++) cout<<a[i]<<' ';
	return 0;
}  

在这里插入图片描述

方法二:手打next_permutation
算法思想:
1.首先从最尾端开始往前寻找两个相邻元素,令第一元素为i,第二元素为ii,且满足i<ii。
2.找到这样一组相邻元素后,再从最尾端开始往前检验,找出第一个大于i的元素,令为j,将i,j元素对调(swap)。
3.再将ii之后的所有元素颠倒(reverse)排序。
不理解可以自己举个例子动手模拟一下!!!

#include <bits/stdc++.h>
using namespace std;
int b[10001],i,j,k,m,n,t;
void work()
{//一个全排列序列,左边部分趋向升序,右边部分趋向降序 
	for(int i=1;i<=m;i++)
	{
		for(j=n-1;j>=1;j--)
		   if(b[j]<b[j+1])//从后往前搜 
		       break;//找到最后可增加的那一位,也是右边序列最大的 
		for(k=n;k>=1;k--)
		   if(b[k]>b[j])//从后往前搜 找到的就是右边部分最小的 
		       break;//找到最小的可增加的数字 
		swap(b[j],b[k]);//交换 
		j=j+1;k=n;
		while(j<k)
		{//右边部分原来趋向升序排列,现在改为降序排列 
			swap(b[j],b[k]);
			j++;k--;
		}
	}
}
int main()
{
	cin>>n>>m;
    for(i=1;i<=n;i++)cin>>b[i];	
	work();
	for(i=1;i<=n-1;i++) cout<<b[i]<<' ';
	cout<<b[n]<<endl;
	return 0;
}  

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38993096/article/details/88374233