康拓展开 讲解+模板

问题:给你一些不重复的元素,将它们从小到大排序,问你某个排列在所有的排列处于第几大;

康拓展开:公式为:X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!(an是n这个数字在所有元素中排第几从0开始算,也就是有几个比n小的数字)

讲解:举个例子现在有4个元素为1,2,3,4,将他们从小到大排序结果如下:

①1 2 3 4    ⑦2 1 3 4    3 1 2 4    4 1 2 3

②1 2 4 3    ⑧2 1 4 3    3 1 4 2    4 1 3 2

③1 3 2 4    ⑨2 3 1 4    3 2 1 4    ㉑4 2 1 3

④1 3 4 2    ⑩2 3 4 1    3 2 4 1    ㉒4 2 3 1

⑤1 4 2 3    2 4 1 3    3 4 1 2    ㉓4 3 1 2

⑥1 4 3 2    2 4 3 1    3 4 2 1    ㉔4 3 2 1

现在问你4 2 1 3在这中序列中排第几位,大家是对照着上面的一眼就看出来了,如果没有这个表呢,如果数字再多几位呢,是不是感觉很难找到他的我位置了,而康拓展开只需要通过一些计算就可以算出来他的位置,而不需要排列出这些元素再去寻找;公式在上面;现在说一下为什么是这样呢;

就比如3这个序列

先看第一位4,比4小的数字有三个1,2,3,所以,以这三个数字开头的排列均小于它,3*(4-1)!为18,

(这一步中比4开头小的有1,2,3,以这三个数字开头,不论后面三个数字怎么排都不会大于它,这就是(4-1)!)

再看第二位2,比2小的数字有一位1,所以,从第二位开始以1开头的排列均小于它,1*(4-1-1)!为2,

(在4排在第一时(即第一步的情况下),这一步中比2开头的数字有一个1,以4 1的顺序排,不论后面怎么排都不会大于它,即(4-1-1)!)

再看第三位1,比1小的数字有零个,所以,0*(4-2-1)!为0,

再看第四位4,比3小的数字有两个1,2然而1,2都排好了所以比三小的数字为零,所以,0*(4-3-1)为0;

X=3*(4-1)+1*(4-1-1)!+0*(4-2-1)!+0*(4-3-1)!=20;

在它前面有20个比他小的,所以他就排在20+1的位置;

看到这应该对康拓展开差不多理解了把,那么代码该怎么写呢?

long long KT(string a)
{
	long long sum=0,cnt,len=a.length();//sum为第几大,cnt为一个临时变量求比当前这个数字小的还有几个,len就是长度 
	for(int i=0;i<len;i++)
	{
		cnt=0;
		for(int j=i+1;j<len;j++)//求cnt 
		{
			if(s[j]<s[i]) cnt++;//在该数后面有几个比他小的数字,即没排的数字中有几个比它小的 
		}
		sum+=cnt*f[len-i-1];//f[x]为x的阶乘 
	}
	return sum;//返回有多少个比它小的排列 
} 

有一道模板题大家可以看看,nwsoj1235我排第几个(我博客有题解需要自找)





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值