火星人

为什么要用全排列??

火星人如果有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;  
    }  

猜你喜欢

转载自blog.csdn.net/qq_39984146/article/details/79162626
今日推荐