首页 > 学院 > 开发设计 > 正文

nyoj 139 我排第几个(康拓展开)

2019-11-08 02:28:47
字体:
来源:转载
供稿:网友

我排第几个

时间限制:1000 ms  |  内存限制:65535 KB难度:3描述

现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的?

输入第一行有一个整数n(0<n<=10000);随后有n行,每行是一个排列;输出输出一个整数m,占一行,m表示排列是第几位;样例输入
3abcdefghijklhgebkflacdjigfkedhjblcia样例输出
1302715242

260726926

AC代码如下:

#include<cstdio>using namespace std;const int maxn=12+2;char s[maxn];int stratum(int n){    //求阶层	int sum=1;	for(int i=1;i<=n;i++){		sum*=i;	}	return sum;}int cantor(){        //康拓展开	int sum=0;for(int i=0;i<12;i++){	int temp=0;	for(int j=i+1;j<12;j++)		if(s[i]>s[j])temp++; 	sum+=temp*stratum(11-i);   }   return sum;} int main(){	int n;	scanf("%d",&n);	while(n--){		scanf("%s",s);		int cnt=cantor();		PRintf("%d/n",cnt+1);	}	return 0;} 

(1)康拓展开

  所谓康拓展开是指把一个整数X展开成如下形式:

  X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0!。(其中,a为整数,并且0<=a[i]<i(1<=i<=n))

(2)应用实例

  {1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按从小到大排列一共6个:123 132 213 231 312 321。他们间的对应关系可由康托展开来找到。

  1324是{1,2,3,4}排列数中第几个大的数:  第一位是1小于1的数没有,是0个 0*3! ;  第二位是3小于3的数有1和2,但1已经在第一位了,即1未出现在前面的低位当中,所以只有一个数2 1*2! ;  第三位是2小于2的数是1,但1在第一位,即1未出现在前面的低位当中,所以有0个数 0*1! ;  所以比1324小的排列有0*3!+1*2!+0*1!=2个,1324是第三个大数。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表