您的位置:首页 > 其它

我排第几个---康托展开

2015-05-05 13:54 162 查看


我排第几个

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

描述

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

输入
第一行有一个整数n(0<n<=10000);

随后有n行,每行是一个排列;
输出
输出一个整数m,占一行,m表示排列是第几位;
样例输入
3
abcdefghijkl
hgebkflacdji
gfkedhjblcia


样例输出
1
302715242
260726926

利用康托展开可以轻松解决这题,

在百度百科上看到一个类似的题

1324是{1,2,3,4}排列数中第几个大的数:

第一位是1小于1的数没有,是0个 0*3! 第二位是3小于3的数有1和2,

但1已经在第一位了,所以只有一个数2 1*2! 。

第三位是2小于2的数是1,但1在第一位,所以有0个数 0*1! ,

所以比1324小的排列有0*3!+1*2!+0*1!=2个,1324是第三个小数。

ps:康托展开公式X=a
*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!

#include <stdio.h>
#include <string.h>

bool visited[20];
int f(int x){
	if (x == 1 || x == 0)
		return 1;
	return x * f(x - 1);
}
int main(){
	int n;
	char a[13];
	scanf("%d", &n);
	getchar();
	int i, j;
	while (n--){
		int sum = 0;
		memset(visited, 0, sizeof(visited));
		gets(a);
		for (i = 0; i < 12; i++){
			visited[a[i] - 97] = 1;
			int res = 0;
			for (j = 0; j < a[i] - 97; j++)
			if (!visited[j])
				res++;
			sum += res * f(11 - i);
		}
		printf("%d\n", sum + 1);
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: