poj 1850 Code

// 题意: 输出某个str字符串在字典中的位置,
// 由于字典是从a=1开始的,因此str的位置值就是在str前面所有字符串的个数+1
// 规定字典的字符串必须是严格升序排列,其他是非法字符串,直接输出0即可
// 例: a = 1; … z = 26; ab = 27, … az = 51; vwxyz = 83681;

#include <iostream> //组合数学
#include <string>
using namespace std;
int C(int n,int m) //求组合数C(n,m)=C(n-1,m)+C(n-1,m-1)
{
if(m==0||n==m)
return 1;
else
return C(n-1,m)+C(n-1,m-1);
}
int main()
{
string str;
cin>>str;
int len=str.size();
for(int i=1;i<len;++i) //判断str是否严格升序序列
{
if(str[i]<=str[i-1])
{
printf("0\n");
return 0;
}
}
int ans=1;
//注意到在题目的要求下n个不同字母的排列可能性只有C(26,n);
//因为对于特定的一组字母,它只可能有一种情况,就是按升序排列
for(int i=1;i<len;++i) //计算比str长度少的所有字符串个数
ans+=C(26,i);
char low='a';
//计算长度等于len,但值比str小的字符串个数
for(int i=0;i<len;++i)
{
for(char ch=low;ch<str[i];ch+=1) //对每一个位置i枚举允许选择的字符ch
{
ans += C( 'z'-ch , len-i-1 );
//假如字符ch填充在位置i上,则后面剩下的len-i-1个字符的组合可能性为C( 'z'-ch , len-i-1 )
//因为<=ch的字符不允许再被选择,所以接下来能够选择的字符总数为'z'-ch
}
low=str[i]+1; //根据升序规则,str下一位置至少要比当前位置的字符大 1
}
cout<<ans<<endl;
return 0;
}

posted on 2011-07-22 19:12  sysu_mjc  阅读(147)  评论(0编辑  收藏  举报

导航