蓝桥杯——排列序数

时间:2021-05-02 11:12:27
标题: 排列序数


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的全排列都比它小,共有1*16!个。
在第一位为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;
}