http://poj.org/problem?id=1850 -----------------http://poj.org/problem?id=1496 两题解法类似。。
本题为组合数学的题,要求所给字符串在排列中的位置。所用的方法为暴力枚举。
对于长度为1的字符串有a,b,c,d.......26个;
长度为2的字符串有 a开头时有ab,ac,ad,ae,af.....(25,1) 25个 //()为组合数
b开头时有bc,bd,de,.....(24,1) 24个
c开头时有cd,ce,cf。。。(23,1) 23个
。。。。。。。
y开头时有yz (1,1) 1个。
所以长度为2的字符串共有 (25,1)+(24,1)+(23,1)+(22,1)。。。。=(26,2);
同理 长度为3时 共有 (26,3)个; 长度为4时有(26,4)个。。。。。
对于长度小于所给字符串的串,,直接相加即可,。。而对于长度等于所给字符串的串需要挨位枚举。。
例如:对于所给串为 dghei 长度等于它的串的个数应这样枚举:
第一位,应从‘a’开始一直枚举到‘c’,,,但是对于‘a’来说 还有‘z’-‘a’个比‘a’大的字符,后边还有4个位置空着,所以仅对于这一位来说是((‘z’-‘a’),4);
第二位, 应从比‘d’的字符开始枚举,因为题目要求是非降序列。。其他类似。。。
1 #include<iostream>
2 #include<cstring>
3 using namespace std;
4 int c[27][27];
5 int main(){
6 for(int i=0;i<=26;i++)//初始化。。
7 for(int j=0;j<=26;j++){
8 if(!j||i==j)
9 c[i][j] = 1;
10 else
11 c[i][j] = c[i-1][j-1]+c[i-1][j];
12 }
13 c[0][0] = 0;
14 char str[15];
15 while(cin>>str){
16 int len = strlen(str);
17 for(int i=1;i<len;i++){
18 if(str[i]<=str[i-1]){
19 cout<<0<<endl;
20 return 0;
21 }
22 }
23 int sum = 0;
24 for(int i=1;i<len;i++)//比所求字符串短的字符串
25 sum += c[26][i];
26 //枚举字符串的每一位
27 for(int i=0;i<len;i++){
28 char cu = !i?'a':str[i-1]+1;//如果是第一位,就从‘a’开始枚举改位的取值,其余的从比前一位大1的位置开始
29 while(cu<=str[i]-1){
30 sum+= c['z'-cu][len-i-1];//剩余的字母数记为‘z’-cu,而还需要选len-(i+1)个
31 cu++;//继续枚举,直到仅比改为小1;
32 }
33 }
34 sum += 1;//加上该字符串本身,,因为之前最大就到该位-1
35 cout<<sum<<endl;
36 }
37 return 0;
38 }