POJ 1850 Code
2015-08-15 10:35
309 查看
Code
Submit Status
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 the words are made
only of small characters of the English alphabet a,b,c, ..., z (26 characters). From all these words we consider only those whose letters are in lexigraphical order (each character is smaller than the next character).
The coding system works like this:
• The words are arranged in the increasing order of their length.
• The words with the same length are arranged in lexicographical order (the order from the dictionary).
• We codify these words by their numbering, starting with a, as follows:
a - 1
b - 2
...
z - 26
ab - 27
...
az - 51
bc - 52
...
vwxyz - 83681
...
Specify for a given word if it can be codified according to this coding system. For the affirmative case specify its code.
Input
The only line contains a word. There are some constraints:
• The word is maximum 10 letters length
• The English alphabet has 26 characters.
Output
The output will contain the code of the given word, or 0 if the word can not be codified.
Sample Input
Sample Output
题意:给定字符串排序规则如下:
只有小写字母,先按照长度拍,长的序号大,在按照字母字典序拍,一个串中字母是升序(自然不能有相同的字母)
a 1
b 2
c 3
......
z 26
ab 27
ac 28
...
az 51
bc 52
.....
vwxyz - 83681
现在输入字符串,求它的编号;
思路:
字符串的规律性很强,先考虑长度问题,加上长度已经固定为x,也就是说由x个字母组成的字符串(满足题目升序要求)有多少种,有26个字母选x个组成一个字符串,
种数就是组合数C(26,x),选出x个字符后排序只有一种(因为选出x个字母肯定没有重复的,既然是不同的x个字母的排列,而且必须升序,不就只有一种排列么-_-:);
那么就是C(26,x)种;对于输入的字符串计算长度为len,那么比len小的字符串比如排在它前面(题目说先按长度排序的),加到答案里既C(26,1)+C(26,2)+.....+C(26,len-1);
然后长度为len比输入字符串小的串的有多少个呢,数位dp咯,每个字母都有数字标号嘛,a对应0,z 对应25,字母位抽象成数字位(只不过数字位可以大于9,+.........+)
然后状态要保存前一位数字,因为题目要求升序,每次枚举都从前一位+1开始;
Time Limit: 1000MS | Memory Limit: 30000KB | 64bit IO Format: %I64d & %I64u |
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 the words are made
only of small characters of the English alphabet a,b,c, ..., z (26 characters). From all these words we consider only those whose letters are in lexigraphical order (each character is smaller than the next character).
The coding system works like this:
• The words are arranged in the increasing order of their length.
• The words with the same length are arranged in lexicographical order (the order from the dictionary).
• We codify these words by their numbering, starting with a, as follows:
a - 1
b - 2
...
z - 26
ab - 27
...
az - 51
bc - 52
...
vwxyz - 83681
...
Specify for a given word if it can be codified according to this coding system. For the affirmative case specify its code.
Input
The only line contains a word. There are some constraints:
• The word is maximum 10 letters length
• The English alphabet has 26 characters.
Output
The output will contain the code of the given word, or 0 if the word can not be codified.
Sample Input
bf
Sample Output
55
题意:给定字符串排序规则如下:
只有小写字母,先按照长度拍,长的序号大,在按照字母字典序拍,一个串中字母是升序(自然不能有相同的字母)
a 1
b 2
c 3
......
z 26
ab 27
ac 28
...
az 51
bc 52
.....
vwxyz - 83681
现在输入字符串,求它的编号;
思路:
字符串的规律性很强,先考虑长度问题,加上长度已经固定为x,也就是说由x个字母组成的字符串(满足题目升序要求)有多少种,有26个字母选x个组成一个字符串,
种数就是组合数C(26,x),选出x个字符后排序只有一种(因为选出x个字母肯定没有重复的,既然是不同的x个字母的排列,而且必须升序,不就只有一种排列么-_-:);
那么就是C(26,x)种;对于输入的字符串计算长度为len,那么比len小的字符串比如排在它前面(题目说先按长度排序的),加到答案里既C(26,1)+C(26,2)+.....+C(26,len-1);
然后长度为len比输入字符串小的串的有多少个呢,数位dp咯,每个字母都有数字标号嘛,a对应0,z 对应25,字母位抽象成数字位(只不过数字位可以大于9,+.........+)
然后状态要保存前一位数字,因为题目要求升序,每次枚举都从前一位+1开始;
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<queue> #include<set> #include<vector> #include<map> #include<stack> #include<cmath> #include<algorithm> using namespace std; const int maxn=1e6+5; const int INF=0x3f3f3f3f; typedef __int64 ll; ll dp[30][30],sum[30],c[30]; int a[30]; bool vis[30]; string s; ll dfs(int pos,int n,int pre,int limit)//数位dp { //基本上是模板,pos保存当前第几位,pre保存上一位字母,然后记忆化搜索 if(pos==n) return 1; if(limit==0 && dp[pos][pre]!=-1) return dp[pos][pre]; int upper=limit?a[pos]:25; ll ans=0; for(int i=pre+1;i<=upper;i++)//合法的字符串是递增的 {//所以i从pre+1,也就是比前一位大一的数开始枚举 ans+=dfs(pos+1,n,i,limit && i==a[pos]);//最后一个参数的处理就是模板,貌似没见过别的写法的; } if(limit==0) dp[pos][pre]=ans; return ans; } void solve() { int pos=0; for(int i=0;i<s.size();i++) a[pos++]=s[i]-'a'; printf("%I64d\n",dfs(0,pos,-1,1)+sum[s.size()-1]); } void C()//递推组合数 { c[0]=1; int n=26; for(int i=1;i<=26;i++) c[i]=c[i-1]*(n-i+1)/i; } void init() { sum[0]=0; C(); for(int i=1;i<=11;i++) { sum[i]+=sum[i-1]+c[i];//组合数的和 } memset(dp,-1,sizeof dp);//初始化放里面也是对的,数位dp的特别之处:每个数满不满足条件只与数本身有关, //只不过每组数据给的区间不一样使得区间外的数不被统计, //当然不同的题这里的处理是不一样的,数满不满足条件如果和输入有关那就只能放里面 } int main() { init(); while(cin>>s) { int tag=0; for(int i=1;i<s.size();i++) if(s[i]<s[i-1]) tag=1;//输入的串要合法 if(tag) { printf("0\n"); continue;//break也行(。。。。); } solve(); } return 0; }
相关文章推荐
- Android(java)学习笔记160:Framework运行环境之 Android进程产生过程
- webrtc 编译汇编文件时错误
- tomact登录问题
- Zookeeper的Java客户端
- HDU 1143 Tri Tiling
- NS3网络仿真(11): ARP
- Java报错原因汇总
- 天天猜拳
- UIVisualEffectView 毛玻璃效果的应用
- 八大排序算法(八)桶排序
- 上传阿里云样式文件不解析问题一例总结
- poj 1703 Find them, Catch them 【并查集 新写法的思路】
- 【转载】软件开发模型对比
- 向右划出侧边栏
- 写给那些让我糊里糊涂的HTTP、TCP、UDP、Socket
- iOS6新特征:UICollectionView介绍
- AngularJs学习笔记__6、自定义过滤器,阿拉伯数字金额转汉字金额
- MySQL同步故障:" Slave_SQL_Running:No"
- 简单解决Ubuntu修改locale的问题
- python 字典访问 items()和iteritems()的区别