我排第几个
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的?
-
输入
-
第一行有一个整数n(0<n<=10000);
随后有n行,每行是一个排列;
输出
- 输出一个整数m,占一行,m表示排列是第几位; 样例输入
-
3 abcdefghijkl hgebkflacdji gfkedhjblcia
样例输出
-
1 302715242 260726926
-
第一行有一个整数n(0<n<=10000);
其实分析题意很简单,就是找到这是第几次排列到的序列,如果用全排列函数也能得到,但一定超时,然后我百度知道,用了康托展开,举例说明康托展开:
起始是:abcdefghijkl;
想要变成hgebkflacdji;
首先第一个字符由a变成h,就要知道它是第8个字符,已经经历过7次11的阶乘变化才能得到h,依次类推;
S=7*11!+6*10!+4*9!+1*8!+10*7!+5*6!+11*5!+0*4!+2*3!+3*2!+9*1!+8*0!=302715242;
#include<stdio.h>
int b[15]= {0,1,2,6,24,120,720,5040,40320,362880,3628800,39916800};
//分别是0,1,2。。。。。的阶乘
int main()
{
int m,i,j,n=0,c=0,sum=0,d[15];
char a[15];
scanf("%d",&n);
while(n--)
{
getchar();//接收多余字符
scanf("%s",a);
sum=0;
for(i=0; i<12; i++)
{
c=0;//初始化本字符的次序
for(j=i+1; j<12; j++)
if(a[j]<a[i])
c++;//统计按照顺序这是第几个字符
sum+=c*b[11-i];//要排列到本字符需要经历的次数
}
printf("%d\n",sum+1);
}
return 0;
}