Permutation

http://acm.bupt.edu.cn/onlinejudge/newoj/showProblem/show_problem.php?problem_id=5

Problem Id: 5
Submit time: 2012-03-06 21:04:57
User_id: 10839
Memory:152K   Time:6MS
Language:G++  Result:Accepted

  • Code
#include<iostream>
#include<algorithm>

const int N=1030;

int data[N],bk[N],n;
void print(int n,int* d)
{
	for(int i=0;i<n-1;i++)
		cout<<d[i]<<" ";
		cout<<d[n-1]<<endl;
		return;
}
void cpy(int* s,int* d)
{
	for(int i=0;i<n;i++)
		d[i]=s[i];
		return;
}
int main()
{
   int k,test,idx;
   cin>>test;
   while(test--)
   {
	   cin>>n>>k;
	   idx=0;
	   for(int i=0;i<n;i++)
	   {
		   cin>>data[i];
		   bk[i]=i+1;
	   }
		   while(idx<k&&next_permutation(data,data+n))
		    idx++;
		if(idx==k)
			print(n,data);
		while(idx<k)
		{
			idx++;
			cpy(bk,data);
			while(idx<k&&next_permutation(data,data+n))
				idx++;
			if(idx==k) print(n,data);
		}
	   
   }
	return 0;
}

next_permutation的简单应用,其实通过查看源码发现其算法设计的巧妙

1 2 3 4----->3 2 1

1 2 4 3----->3 2 0

-----

4 3 1 2----->0 0 1 

4 3 2 1----->0 0 0 

其实左边和右边存在一一对应的关系,右边的三个数的意义是 

1 2 3 4----->3 2 1: 1后面比1大的数有 ‘3’个,2后面比2大的数有‘2’个,3后面比3大的数有‘1’个,4因为在最后所以其后比他大的数不存在可以省去。

如果给右边的3个数字 每一位赋予一个阶的话,就可以用一个数来表示3个数了

关键就在于如何设计阶:

                  (3*3+2)*2+1=23

                  (3*3+2)*2+0=22

       (3*3+1)*2+1=21

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

                  (0*3+0)*2+0*1=0

所以说用0~23即可以代表任何一个排列 

也就是说 18所代表的排列的下一个排列为17 =(2*3+2)*2+1 也就是排列 2 1 3 4

 

转载于:https://www.cnblogs.com/wuzhibin/archive/2012/03/06/2382633.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值