康托展开【全排列】

康托展开

题目描述

给出一个数N,再给出N的全排列的某一个排列,问该排列在全排列中的次序是多少?例如3的全排列中,123排第一位,321排最后一位

输入描述

第一行为一个数N,第二行为N的全排列的某一个排列

输出描述

一个整数,表示该排列在全排列中的次序

样例

输入

3
1 2 3

输出

1

思路

设有 n 个数,可以有组成不同(种)的排列组合,康托展开表示的就是是当前排列组合在 n 个
不同元素的全排列中的名次。

那我们首先确定肯定不能暴力
因为本题范围是20,而20个字符全排列是一个很恐怖的数字
是多少呢? 20 ! 20! 20! 2.432902 e + 18 2.432902e+18 2.432902e+18
翻译成是个人都能看懂的就是 2.432902 × 1 0 18 2.432902\times10^{18} 2.432902×1018
这别说是时间超限都够时间它轮回一趟了
那我们就该引入本题的正解了:
观察样例,由于本题是字典序排列,所以只要比排列数小的数字都该排在它的前面
单说可能不太直观,举个例子25431
先看万位2:
因为比25431小的排列数都该排在它的前面,所以以1开头的排列数就都排在了它的前面
以1开头的五位排列数有多少呢?
4 ! 4! 4! 因为第一位确定是1然后剩下四位全排列
所以25431光万位可以排除 1 × 4 ! 1\times4! 1×4!个数,注意假如万位是 x x x是相应的要把1改成 x − 1 x-1 x1
同理,观察往后的数,可得25431前面有:
X = X= X= 1 × 4 ! + 3 × 3 ! + 2 × 2 ! + 1 × 1 ! + 0 × 0 ! 1\times4!+3\times3!+2\times2!+1\times1!+0\times0! 1×4!+3×3!+2×2!+1×1!+0×0!个数
所以我们可以总结成公式的形式:
X = X= X= a [ 1 ] × ( n − 1 ) ! + a [ 2 ] × ( n − 2 ) ! + a [ 3 ] × ( n − 3 ) ! + . . . + a [ n − 1 ] × 0 ! a[1]\times(n-1)!+a[2]\times(n-2)!+a[3]\times(n-3)!+...+a[n-1]\times0! a[1]×(n1)!+a[2]×(n2)!+a[3]×(n3)!+...+a[n1]×0!
之后的代码相信聪明的读者是可以自己写出来哒( ̄▽ ̄)~*
注意:由于康托展开求的是输入排列数前面有多少排列数,所以算出答案要+1

AC代码

#include<iostream>
#include<cstdio>

using namespace std;

int N;
int a[25]; //排列数组
long long p[25]; //阶乘数组
long long sum = 1; //次序

//康托展开函数(模版,建议寄到小本本上(`・ω・´))
long long cantor(int n) {
	//阶乘
	p[0] = 1;
	for (int i = 1; i <= 15; i++) {
		p[i] = p[i - 1] * (i + 1);
	}
	//重中之重
	long long s = 0;
	for (int i = 0; i < n - 1; i++) {
		//枚举当前位前面有多少个数没有被用过
		s = 0;
		for (int j = i + 1; j < n; j++) {
			if (a[i] > a[j]) {
				s++;
			}
		}
		sum += s * p[n - 2 - i];  //用可用数数量*阶乘
	}
	return sum;
}

int main() {
	scanf("%d", &N);
	for (int i = 0; i < N; i++) {
		scanf("%d", &a[i]);
	}
	printf("%lld", cantor(N));
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值