藍橋杯-排列序數

為啥不能重名發表於2020-10-01

X星系的某次考古活動發現了史前智慧痕跡。
這是一些用來計數的符號,經過分析它的計數規律如下:
(為了表示方便,我們把這些奇怪的符號用a~q代替)

abcdefghijklmnopq 表示0
abcdefghijklmnoqp 表示1
abcdefghijklmnpoq 表示2
abcdefghijklmnpqo 表示3
abcdefghijklmnqop 表示4
abcdefghijklmnqpo 表示5
abcdefghijklmonpq 表示6
abcdefghijklmonqp 表示7
……

在一處石頭上刻的符號是:
bckfqlajhemgiodnp

請你計算出它表示的數字是多少?

請提交該整數,不要填寫任何多餘的內容,比如說明或註釋。

思路:本題其實就是求排列bckfqlajhemgiodnp是abcdefghijklmonqp的第幾個全排列,
因為長度為n的全排列有n!個,首先看第一位為b,那麼第一位為a的全排列都比它小,共有116!個。
在第一位為b的狀態下,其次看第二位為c,那麼第二位為a,b的全排列都比它小,但是第一位為b很顯然
第二位不能為b了所以共有1
1*15!,以此類推,到最後就可以算出在此全排列之前的所有全排列了。
設一個標記陣列vis記錄前幾位用過的數字,在程式中為了方便起見把原題中的字串減去字元a的acsll
碼值變為整數陣列。

#include<bits/stdc++.h>


using namespace std;

//求階乘
long long fun(long long n)
{
    long long s = 1;
    for(int i = 1; i <= n; i++)
        s *= i;
    return s;
}


int main()
{
    long long ans = 0;
    int vis[20];
    memset(vis, 0, sizeof(vis));
    int a[] = {2,3,11,6,17,12,1,10,8,5,13,7,9,15,4,14,16};
    for(int i = 0; i < 17; i++)
    {
        int f = 0;
        for(int j = 1; j <= 17; j++)
        {
            if(j == a[i])
            {
                vis[j]=1;
                break;
            }
            if(vis[j]==0)
                f++;
        }
        ans += f * fun(16-i);
    }
    printf("%lld\n", ans);
    return 0;
}