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
#include
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