码迷,mamicode.com
首页 > 其他好文 > 详细

poj1850 Code【组合数学】By cellur925

时间:2018-09-27 23:57:10      阅读:288      评论:0      收藏:0      [点我收藏+]

标签:这一   多少   mes   block   img   %s   strlen   序列   ret   

题意:

* 按照字典序的顺序从小写字母 a 开始按顺序给出序列 (序列中都
为升序字符串)
* a - 1
* b - 2
* ...
* z - 26
* ab - 27
* ...
* az - 51
* bc - 52
* ...
* vwxyz - 83681
* 输入字符串由小写字母 a-z 组成字符串为升序,根据字符串输出
在字典里的序列号为多少。

很容易地我们可以想到,设输入的字符串长度为len,我们可以用组合数求出所有小于len长度的字符串数量,(感觉这一步很好理解,反而许多题解给出了详细的证明?)。

然后我们开始求当前长度的字符串,一步一步逼近目标串。

因为它是依照字典序排序的,所以我们珂以利用这一性质确认从多少字母中选出多少个。

Code

技术分享图片
 1 //poj1850
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring> 
 5 
 6 using namespace std;
 7 typedef long long ll;
 8 
 9 int last,ans;
10 int c[50][50];
11 char r[50];
12 
13 int C(int a,int b)
14 {
15     return c[a][b];
16 }
17 
18 void pre()
19 {
20     for(int i=0;i<=30;i++) c[i][0]=1;
21     for(int i=1;i<=30;i++)
22         for(int j=1;j<=i;j++)
23             c[i][j]=c[i-1][j]+c[i-1][j-1];
24 }
25 
26 int digit(int x)
27 {
28     return (int)r[x]-96;
29 }
30 
31 int main()
32 {
33     pre();
34     scanf("%s",r+1);
35     for(int i=1;i<strlen(r+1);i++)
36         if(r[i]>r[i+1]) {printf("0");return 0;}
37     for(int i=1;i<=strlen(r+1)-1;i++)
38         ans+=C(26,i);
39     for(int i=1;i<=strlen(r+1);i++)
40     {
41         int pos=digit(i);
42         for(int j=last+1;j<pos;j++)
43             ans+=C(26-j,strlen(r+1)-i);
44         last=pos;
45     }
46     printf("%d",ans+1);
47     return 0;
48 } 
View Code

 

poj1850 Code【组合数学】By cellur925

标签:这一   多少   mes   block   img   %s   strlen   序列   ret   

原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9716118.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!