nBOJ5 - Permutation

Permutation
Accept:113     Submit:308
Time Limit:1000MS     Memory Limit:65536KB

Description

 

We all know that , when there are n positive integers (namely 1…n) , we can use these n integers to construct n! kinds of permutations . Sort these permutations in lexicographic order . For example , when n = 3 , we can permute 1 2 3,1 3 2,2 1 3, 2 3 1, 3 1 2 , 3 2 1 these 6 kinds of permutations.

Now , we want to know , with the given permutation , calculate the next k permutation . If the permutation is the last permutation in order , its next permutation is the first permutation , namely 1 2 3 … n.

e.g. when n = 3 , k = 2 , giving the permutation 2 3 1 , thus its next 1 permutation is 3 1 2 , its next 2 permutation is 3 2 1 , so the answer is 3 2 1 .

Input

 

The first line is a positive integer m , indicating the number of test cases . Then m test cases . In every test case , the first line is 2 positive integers n (1 <= n < 1024) and k (1 <= k <= 64) ; the second line are n positive integers , which is one of the  “ 1 2 3 … n”  s’ permutation.

 

Output

 

For each test case , print one line , n numbers , with spaces separating every number , indicating the given permutation ‘s next k permutation.

 

Sample Input

 

3

3 1

2 3 1

3 1

3 2 1

10 2 

1 2 3 4 5 6 7 8 9 10

Sample Output

 

3 1 2

1 2 3

1 2 3 4 5 6 7 9 8 10



其实刚看到的时候没什么思路。但是想到了STL的next_permutation,于是就搜了一下这个库函数的实现。

具体的操作是从右边开始搜两两相连的数,直至发现一组满足右边>左边,然后把左边的位置标记为x,然后从最右边开始搜索直至发现满足大于这个数的第一个数,将其位置标记为y,然后交换x与y位置的元素,然后将x之后的所有元素逆置。


比如序列1,5,3,4,2,6,8,9,10,7

第一组满足右边>左边的是[9,10],然后第一个大于9的元素是10,那么交换9和10元素的位置,然后将10之后所有元素逆置,既1,5,3,4,2,6,8,10,7,9

再看这组数列的下一排列,第一个满足右边>左边的是[7,9],那么下一排列是1,5,3,4,2,6,8,10,9,7

同理,再下一组排列的变化过程是

1,5,3,4,2,6,8,109,7 --> 1,5,3,4,2,6,910,8,7 --> 1,5,3,4,2,6,9,7,8,10


代码分析见:http://apps.hi.baidu.com/share/detail/19561533


 

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<numeric>
#include<cstdio>

using namespace std;

int main(void)
{
int m(0),n,k;
scanf("%d",&m);

while(m--)
{
scanf("%d%d",&n,&k);
int *p = new int[n];
for(int i(0);i != n;++i)
scanf("%d",&p[i]);

while(k--)
if(!next_permutation(p,p+n))//返回值为false表示是最后一组排列,那么排序为升序即可回到第一组
sort(p,p+n);

for(int i(0);i != n-1;++i)
printf("%d ",p[i]);
printf("%d\n",p[n-1]);

delete[] p;
}

return 0;
}



posted @ 2012-03-02 08:15  codejustforfun  阅读(194)  评论(0编辑  收藏  举报