luogu_2524【题解】康托展开

题目:https://www.luogu.org/problemnew/show/P2524

明显的康托展开可以解决的问题。

康托展开:

  用一个数表示一个序列,这个数就是这个序列在所有序列中的字典序排名。

  用洛谷上一个大佬的例子。

  序列:24513

  第一个数是2,比2小的而且没有确定的只有1个数1。所以 ans +=( 1 * ( 4! ) )。

  第二个数是4,比4小的而且没有确定的有2个数1,3。所以 ans += ( 2 * ( 3! ) )。

  以此类推,都是这样的。

  最后到1和3没有更小的了,自然不加。

  ans=40。所以位数就是41。

  最后放上公式:X=a[n] [(n-1)!] + a[n-1][(n-2)!] + .... + a[1] * [0!]。(a[i]表示在i第位之前,有几个比它小还没确定的数。)

这个题自然就解决了。代码如下。

#include<bits/stdc++.h>
using namespace std;
const int f[]={1,1,2,6,24,120,720,5040,40320,362880};
int n;
char s[100];
inline int Contor(){
    int ans=0;
    for(int i=0;i<n;i++){
        int small=0;
        for(int j=i+1;j<n;j++)
            if(s[j]<s[i]) small++;
        ans+=small*f[n-i-1];
    }
    return ans+1;
}
int main()
{
    scanf("%d",&n);
    scanf("%s",s);
    printf("%d
",Contor());
    system("pause");
    return 0;
}

ps:看见题解大佬先把阶乘都求出来存下来,我也就复制了一波。(滑稽)

原文地址:https://www.cnblogs.com/ChrisKKK/p/10859085.html