poj1850 Code【组合数学】By cellur925

题意:

* 按照字典序的顺序从小写字母 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 } 

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

时间: 2024-10-27 19:14:30

poj1850 Code【组合数学】By cellur925的相关文章

POJ1850——Code(组合数学)

Code DescriptionTransmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is that one where a number is associated to a character sequence. It is considered t

poj1496 Word Index / poj1850 Code(组合数学)

poj1850 Code 题意:输出若干个给定的字符串($length<=10$)在字典序中的位置,字符串中的字母必须严格递增. 读取到非法字符串时,输出“0”,终止程序.(poj1496:继续读取) 我们分成2种情况讨论字典序小于给定字符串的字符串个数 1.长度比给定字符串小 其实长度为$i$的字符串的个数就是$C(26,i)$ 因为我们随机选取$i$个字符后,从小到大依次取出,是可以保证字符串是有序的. 2.长度等于给定字符串 我们枚举每一位,计算从该位开始小于给定字符串的个数,同样可以用组

POJ1850 Code 【排列组合】

还不算是难题(嘿嘿,因为我做出来了) 很简单,找到相应的方程式解就是了(中间也犯了一个很2的错误,把9+10+11+...+99写成(1+90)*90/2,改过来后就好了) 不多说,code is below #include <iostream> #include <cstdio> #include <cstring> using namespace std; int combi(int a,int b) { int sum=1; int j=1; for(int i

POJ 1850 Code 组合数学

Description Transmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is that one where a number is associated to a character sequence. It is considered that

poj1850(Code)

题目地址:Code 题目大意: 按照字典序的顺序从小写字母a开始按顺序给出序列 a - 1     b - 2     ...     z - 26     ab - 27     ...     az - 51     bc - 52     ...     vwxyz - 83681     ... 输入字符串由小写字母a-z组成字符串为升序,根据字符串输出在字典里的序列号为多少. 解题思路: 排列组合,记住公式: 先看字符的长度一个字符的时候是26为C(26,1),两个字符的时候分别从以a

poj:1850 Code(组合数学?数位dp!)

题目大意:字符的字典序依次递增才是合法的字符串,将字符串依次标号如:a-1 b-2 ... z-26 ab-27 bc-52. 为什么题解都是组合数学的...我觉得数位dp很好写啊(逃 f[pos][pre]前pos位,前一位是pre有几个满足条件的字符串,其实等同于这个字符串的序号是多少 好像数位dp的博客真没什么东西好写的... #include<iostream> #include<cstring> #include<cstdlib> #include<cs

POJ1850 Code【全排列】

题目链接: http://poj.org/problem?id=1850 题目大意: 给你一个字符串str,输出str在字典序全排列中的位置(从小到大排列). 解题思路: 参考博文:http://www.cnblogs.com/lyy289065406/archive/2011/07/31/2122760.html 先判断str是不是升序序列,如果是升序序列,则为字典序的第1个,输出1. 不符合第一步的话,则分为两步计算str的字典序位置. 先计算比 str 的长度少的字符串总个数. 再计算长度

POJ1850 Code(组合+康托展开)

题目问一个合法字符串的字典序是第几个,合法的字符串是指里面的字符严格递增. 先判断合不合法,然后用类似康托展开的过程去求.大概过程就是用组合数算出某长度某前缀有几个,累加起来. 真难一遍写对.. 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 bool islegal(char *s){ 5 for(int i=1; s[i]; ++i){ 6 if(s[i]<=s[i-1]) return 0;

杭电ACM分类

杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDIATE DECODABILITY