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\n",Contor()); system("pause"); return 0; }
ps:看见题解大佬先把阶乘都求出来存下来,我也就复制了一波。(滑稽)