思路:
全排列。
为什么要用全排列?
因为火星人如果有\(1\)个手指头 那只能表示一个数字了。
火星人如果有两个手指头,那么显然有\(12\)和\(21\)两种表示
火星人如果有三个手指头,那么第三个手指头可以放在前两个手指头的左边 中间、或者右边,也就是说不管前两个手指头是\(12\) 还是\(21\),第三个手指头都有3种放法,那么一共就是\(2*3=6=3!\)种了……
如果火星人的前\(k-1\)个手指头有\((k-1)!\)种排列方式,那么不论前\(k-1\)个手指头如何排列,多的一个手指头可以放到最前面,或者是任意一个已知手指头的后面,也就是\(1+k-1=k\)种。那么\(k\)个手指头就有\(k!\)种排列了。
数学归纳,说明了\(n\)个手指头 就是\(n!\)个方法
但是题目所给的\(N\)特别大,而且排列为随机给定,所以用朴素的递归求排列只能通过一小部分数据。但是观察后发现要加上去的\(M\)很小,所以转而求给定排列的后\(m\)个排列...
STL有一个全排列函数,在此把这位大佬介绍的给大家看看:传送门
Code
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 10000+5;
int num[maxn];
int main()
{
int n,m;
while( scanf("%d%d",&n,&m) == 2)
{
for( int i = 0; i < n; i++)
scanf("%d",&num[i]);
for( int i = 0; i < m; i++)
next_permutation(num,num+n); //求全排列
for( int i = 0; i < n; i++)
printf(i==n-1?"%d\n":"%d ",num[i]);
}
return 0;
}