ZCMU-1518-两种全排列的题。

链接:点击打开链接

1518: A Permutation Problem

Time Limit: 1 Sec   Memory Limit: 32 MB
Submit: 56   Solved: 17
[ Submit][ Status][ Web Board]

Description

A long time ago, there was a boy called ZDD. One day he studied the algorithm of permutation. The meaning of permutation is that choosing M different elements from N different elements, and arranged in a certain order. What’s more, if N=M, it’s called full permutation. For example, if N=3 and the sequence is “1 2 3”. The first permutation is “1 2 3”. The second permutation is “1 3 2”. The third permutation is “2 1 3”. The fourth permutation is “2 3 1”. The fifth permutation is “3 1 2”. And the last permutation is “3 2 1”. Now the problem is coming, Giving a sequence S with N elements, each element is in the range of [1,n], and each of them is different. Can you tell him what is the order number of this sequence in full permutation?

Input

         The first line is an integer T, which indicates the number of test case.

For each test case, there is an integer N (1<=N<=100), which indicates the number of element in the sequence, and then following N elements, denoting the sequence S.

Output

        For each test case, you should print the order of the sequence in one line.

Sample Input

2
3 1 2  3
3 3 2 1

Sample Output

1
6


在n比较大的时候调用next_permutation会超时。

第一类题

找出第16个n = 5的序列(12345)

首先第十六个也就是要前面有15个数,

求第一位,15 / 4! = 0 …15  =》  第一位后面有0个数比他小的数是1,所以第一位是1

求第二位,拿走刚才的余数15,用15 / 3! = 2 …3   =>  第二位后面有两个数比他小的是4(1已经没了),所以第二位是4

求第三位,拿走余数3, 用 3 / 2! = 1 …1   =》  第三位后面有一个数比他小的是3,所以第三位是3

求第四位,拿走余数1, 用 1/  1! = 1 …0    =>  第四位后面有一个数比他小的是 5(只剩2和5了),所以第四位是5

最后只剩下一个2。

所以排列是 1,4,3,5,2

第二类题

已知是n = 5,求14352是它的第几个序列?(同一道题)

用刚才的那道题的反向思维

第一位是1,后面有0个数小于1,即0* 4!

第二位是4,后面有2个数小于4,即2* 3!

第三位是3,后面有1个数小于3,即1* 2!

第四位是5,后面有1个数小于5,即1* 1!

第五位是2,不过不用算,因为肯定是0

所以14352是 n = 5的第 0 + 12 + 2 + 1 + 0 = 15    + 1(求的是第几个,所以要加一) = 16

第16个,跟刚才那道题一样,证明对了

最后还涉及到大数,所以最好用java吧:

import java.math.*;
import java.util.*;
public class Main{
public static void main(String[] args) {
    Scanner cin=new Scanner(System.in);
    BigInteger a[]=new BigInteger[110];
    a[1]=BigInteger.valueOf(1);
    a[0]=BigInteger.valueOf(1);
    for(int i=2;i<=100;i++)
    {
        a[i]=a[i-1].multiply(BigInteger.valueOf(i));
    }
    int t=cin.nextInt();
    int b[]=new int[110];
    for(int i=0;i<t;i++)
    {
        int x=cin.nextInt();
        BigInteger ans=BigInteger.valueOf(0);
        for(int j=1;j<=x;j++)
        {
            b[j]=cin.nextInt();
        }
        for(int j=1;j<=x;j++)
        {
            int num=0;
            for(int k=j+1;k<=x;k++)
                if(b[j]>b[k]) num++;
            ans=ans.add(a[x-j].multiply(BigInteger.valueOf(num)));
        }
        ans=ans.add(BigInteger.valueOf(1));
        System.out.println(ans);
    }
 }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值