题目
编码工作常被运用于密文或压缩传输。这里我们用一种最简单的编码方式进行编码:把一些有规律的单词编成数字。
字母表中共有26个字母a,b,c,⋯,z,这些特殊的单词长度不超过6且字母按升序排列。把所有这样的单词放在一起,按字典顺序排列,一个单词的编码就对应着它在字典中的位置。
例如:
- a→1;
- b→2;
- z→26;
- ab→27;
- ac→28。
你的任务就是对于所给的单词,求出它的编码。
输入输出格式
输入格式
仅一行,被编码的单词。
输出格式
仅一行,对应的编码。如果单词不在字母表中,输出0。
输入输出样例
输入样例
ab
输出样例
27
解析
:在n个数中选出m个数的方案总数。
计算公式是或者
通常的,
那么组合数与这题到底有什么关系呢?
拿cgx
举例,设ans为比cgx
小的单词个数,初值为0。
1.首先,cgx
肯定比只有一个字母的单词大,ans+26,ans=26。
2.其次,cgx
肯定比只有两个字母的单词大。
只有两个字母的单词个数该怎么算呢?就是在26个字母中选2个。
3.只有三个字母
3.1第一位:它比以字母a-b
为第一位的大( cgx
第一位为c
,所以要比c
小)
-
以
a
为第一位,且有三位的单词个数:从比
a
大的剩下25个字母中选2个字母: ans+300,ans=351+300=651。 -
以
b
为第一位,且有三位的个数:从比b大的剩下24个字母中选2个字母:ans+276,ans=651+276=927。
3.2第二位(即第一位已经确定为c):它比以字母d-f
为第二位的单词大 (第一位为c
,所以要比c
大,第二位为g
,所以要比g
小)
-
第二位为
d
的个数:。从比
d
大的剩下22个字母中选1个字母:ans+22,ans=927+22=949。 -
第二位为
e
的个数:,ans+21,ans=949+21=970。 -
第二位为
f
的个数:,ans+20,ans=970+20=990。
3.3第三位(一,二位已经确定):它比以字母h-w
为第三位的大,共有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;
}