擅长排列的小明STL

排列组合的题目 分为两种解法:递归解法 非递归解法

其中 最容易的在本人看来就是非递归解法中的字典序 在C++中有一个函数是next_permutation(str.begin(),str.end());

使用它可以轻松全排列一个字符串 如果是无序字符串求全排列 一般都会对字符串进行sort排序 但本题是有序的 所以不需要用到sort

主要是大家一定要会用next_permutation(str.begin(),str.end());这个函数 最好的方法就是自己测试调试 下面我会给出测试代码

大家可以自己来调一下 以便迅速上手 不要看到这个函数就怕了 其实很简单 自己调一调就懂了

 如果存在str之后的排列,就返回true。如果str是最后一个排列没有后继,返回false,每执行一次,str就变成它的后继

#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
int main()
{
	string str;
	cin>>str;
	while(next_permutation(str.begin(),str.end()))
	{
		cout<<str<<endl;
	}
}

还有不了解字典序是什么或者是全排列是什么的童鞋看这里http://blog.csdn.net/laojiu_/article/details/51115352

我这里打博客主要是为了的总结方便复习~

那么这道题其实非常简单 连n个数的全排列都能求出来 那么在n个中取m个不是更加简单么 只需要输出n全排列的前m个数就好了啊

唯一需要注意的就是不要重复就好了 这里可以用set 但是其实再创一个字符串 判是否相等 不等输出就好了 

用C语言如何解决呢


第一步:先从一个排列的最后一位p[n]向前找 找到 第一个递减的位置 p[i-1]<p[i] 记录下i-1的位置

第二步:从位置i开始向后找 找到最后一个大于p[i-1]的数 并记录下表为key

第三步:交换i-1和key位置的元素

第四步:反转i-1位置之后的所有元素

以上四步做完即得到了str的下一个排列 如 132 的下一个排列  

第一步:记录i-1的位置为0 因为13 是从右边找第一个递减的位置 1<3

第二步:找到最后一个大于i-1位置的数为2并记录它的下标key=2

第三步:将i-1位置 和key位置的值交换 得到231

第四步:将i-1位置之后的元素翻转 也就是将0位置之后的元素翻转 得到132的下一个排列为213

如果以上都看懂了 那么这道题就很好解出来了 并且以后碰到排列的题 几乎都可以用到以上这些方式 

有了next_permutation()妈妈再也不用担心我A不出题了~

直接上代码

哦 还有非常重要的一点忘记说了 在算法竞赛中 一旦用到排列组合 记得用C来写输入输出

如果用C++来写cin cout很容易超时 交题的话要交C++而不交G++今天刷另一道题的惨痛教训

#include <iostream>
#include <algorithm>
#include <set>
#include <cstdio>
#include <cstdlib>
#include <string.h>
using namespace std;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m;
		char ch;
		string s1,s2=" ";
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
		{
			ch='0'+i;
			s1+=ch;
		}
		do
		{
			if(s2!=s1.substr(0,m))
			cout<<s1.substr(0,m)<<endl;
			s2=s1.substr(0,m);
		}while(next_permutation(s1.begin(),s1.end()));
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值