POJ 1833 1146 1256 全排列系列 next_permutation函数

    练习到全排列系列的问题,回溯法之类的方法都可以解决。但是在STL中有一个next_permutation函数,可以非常简单便捷地实现全排列功能。

    next_permutation函数的实现是将一个数据组合转化成它的下一个字母序稍大的组合,当数据组合为递减组合时返回0。在此简述该函数执行原理:对一个排列组合求它的下一个排列组合时,首先找到一组相邻的i和ii数,且a[i]<a[ii],再从末尾开始找到第一个大于a[i]的数,记其下标为j,j可与ii下标重合,交换i和j下标所指向元素,将a[ii]下标后的元素颠倒顺序,包括a[ii]。举例:1 5 2 4 3 找到第一组相邻的符合要求的数 i 2  ii 4 自末尾找到第一个大于i下标指向的数  此时j为3 交换i 和j 下标指向数 此时排列组合为 15 3 4 2 最终将ii下标往后的元素颠序  最终生成组合 1 5 3 2 4

    使用next_permutation很容易地AC了几道全排列系列的题目。给出AC代码:

    POJ 1833:

#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=1030;
int a[maxn];
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n,k;
		scanf("%d%d",&n,&k);
		for(int i=0; i<n; i++)
			scanf("%d",&a[i]);
		/*	do
			{
				for(int i=0; i<n; i++)
					printf("%d%c",a[i],i==n-1?'\n':' ');
			} //打印全排列
			while(next_permutation(a,a+n));*/
		for(int i=0; i<k; i++)
			next_permutation(a,a+n);
		for(int i=0; i<n; i++)
			printf("%d%c",a[i],i==n-1?'\n':' ');
	}
	return 0;
}
//next_permutation 当数组为递减顺序排列时返回 flase
//所以如果需要输出全排列时  需要事先排成升序
//该题 求的是往后之后的第k个序列 执行k次函数即可 不需要 顾忌返回值
//perv_permutation 函数相同原理
    POJ  1146:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=55;
char a[maxn];
int main()
{
	while(scanf("%s",a)&&strcmp(a,"#"))
	{
		int len=strlen(a);
		if(next_permutation(a,a+len))
			printf("%s\n",a);
		else
			printf("No Successor\n");
	}
}
    POJ 1256 需要注意根据题目要求自定义cmp函数
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
const int maxn=15;
char a[maxn];
int cmp(char a,char b)
{    //定义大小 
	if(islower(a)&&islower(b))
		return a<b;
	if(isupper(a)&&isupper(b))
		return a<b;
	if(islower(a)&&isupper(b))//a小写 b大写
	{
		if(a-32==b) //如果此时是 a 和A 的情况 
			return 0;
		else
			return  a-32<b;
	}
	if(isupper(a)&&islower(b))//a 大写  b小写 
	{
		if(a==b-32)
			return 1;
		else
			return  a<b-32;
	}
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%s",a);
		int len=strlen(a);
		sort(a,a+len,cmp);
		do
		{
			printf("%s\n",a);
		}
		while(next_permutation(a,a+len,cmp));
	}
	return 0;
}
    STL库有很多便捷高效的算法,待探索。

    特记下,以备后日回顾。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值