题目链接:点击打开链接
题意:a,b,c,...,z 26个字母组成word,并要求word内每个字母成升序排列,按字典序对这些words从1开始进行编码。给定一个word输出编码。
思路:易得,长度为k的word总共有C(k, 26)个(即取k个按升序排序)。对于一个给定的word,不妨先算出从到该word长度的所有word数,再算出与该word长度相等但字典序比它大的words数,相减即可。
要计算与该word长度相等但字典序比它大的words数,即对其每一位,计算比该位字母大的字母数量,设为t,该字母到末尾长度(包括该字母)长度为l,则在该位比word大的words数为C(t, k) ,与前面同理。 遍历一遍即可。
AC代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
using namespace std;
#define FSIO ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a) cout<<"DEBUG: "<<(a)<<endl;
string word;
const int MAXN = 30;
long long cnt[MAXN][MAXN];
void init()
{
cnt[0][0] = 1;
for(int i=1;i<MAXN;++i)
{
cnt[i][0] = 1;
for(int j=1;j<=i;++j)
cnt[i][j] = cnt[i][j-1]*(i-j+1)/j;
}
}
int check()
{
for(int i=0;i<word.length();++i)
{
for(int j=0;j<i;++j)
if(word[i]<=word[j]) return 0;
}
return 1;
}
long long solve()
{
long long res = 0;
int len = word.length();
for(int i=1;i<=len;++i)
{
res += cnt[26][i];
}
long long les = 0;
for(int i=0;i<len;++i)
{
int t = word[i] - 'a' + 1;
les += cnt[26-t][len-i];
}
return res-les;
}
int main()
{
init();
while(cin>>word)
{
if(!check()) cout<<0<<endl;
else cout<<solve()<<endl;
}
return 0;
}