P1246 编码题解

题目

编码工作常被运用于密文或压缩传输。这里我们用一种最简单的编码方式进行编码:把一些有规律的单词编成数字。

字母表中共有26个字母a,b,c,⋯,z,这些特殊的单词长度不超过6且字母按升序排列。把所有这样的单词放在一起,按字典顺序排列,一个单词的编码就对应着它在字典中的位置。

例如:

  • a→1;
  • b→2;
  • z→26;
  • ab→27;
  • ac→28。

你的任务就是对于所给的单词,求出它的编码。

输入输出格式

输入格式

仅一行,被编码的单词。

输出格式

仅一行,对应的编码。如果单词不在字母表中,输出0。

输入输出样例

输入样例

ab

输出样例

27

解析

C_{n}^{m}:在n个数中选出m个数的方案总数。

计算公式是C_{n}^{m}=\frac{\prod _{n-m-1}^{n}}{m!}​​或者C_{n}^{m}=\frac{n!}{m!\left ( n-m \right )!}

通常的,C_{n}^{0}=1

那么组合数与这题到底有什么关系呢?

cgx举例,设ans为比cgx小的单词个数,初值为0。

1.首先,cgx肯定比只有一个字母的单词大,ans+26,ans=26。

2.其次,cgx肯定比只有两个字母的单词大。

只有两个字母的单词个数该怎么算呢?就是在26个字母中选2个。

ans+C_{26}^{2},C_{26}^{2}=\frac{26*25}{2*1}=325,ans=26+325=351

3.只有三个字母

3.1第一位:它比以字母a-b为第一位的大( cgx第一位为c,所以要比c小)

  • a为第一位,且有三位的单词个数:C_{25}^{2}=\frac{25*24}{2*1}=300

    a大的剩下25个字母中选2个字母: ans+300,ans=351+300=651。

  • b为第一位,且有三位的个数:C_{24}^{2}=\frac{24*23}{2*1}=276

    比b大的剩下24个字母中选2个字母:ans+276,ans=651+276=927。

3.2第二位(即第一位已经确定为c):它比以字母d-f为第二位的单词大 (第一位为c ,所以要比c大,第二位为g,所以要比g小)

  • 第二位为d的个数:C_{22}^{1}=\frac{22}{1}=22

    从比d大的剩下22个字母中选1个字母:ans+22,ans=927+22=949。

  • 第二位为e的个数:C_{21}^{1}=21,ans+21,ans=949+21=970。

  • 第二位为f的个数:C_{20}^{1}=20,ans+20,ans=970+20=990。

3.3第三位(一,二位已经确定):它比以字母h-w为第三位的大,共有16个。

\sum_{n=8}^{23}C_{n}^{0}=\sum_{n=8}^{23}1=16*1=16

因为比cgx小的单词共有1006个,所以cgx是第1007个。

#include<iostream>
#include<cstring>
using namespace std;
int ans,n;
string s;
int c(int m,int n){
	if(m==0){
		return 1;
	}
	int mul=1;
	for(int i=n;i>n-m;i--){
		mul*=i;
	}
	for(int i=m;i>1;i--){
		mul/=i;
	}
	return mul;
}
int main(){
	cin>>s;
	n=s.size();
	for(int i=1;i<n;i++){
		if(s[i]<=s[i-1]){
			cout<<0;
			exit(0);
		}
	}
	for(int i=1;i<n;i++){
		ans+=c(i,26);
	}
	for(int i=0;i<n;i++){
		for(char j=(i==0 ? 'a':s[i-1]+1);j<s[i];j++){
			ans+=c(n-i-1,'z'-j);
		}
	}
	cout<<++ans;
	return 0;
}
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值