POJ 1850.Code

题目:http://poj.org/problem?id=1850

AC代码(C++):

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include <math.h>
#include <string>
#include <string.h>
#include <bitset>

#define INF 0xfffffff
#define MAXN 100105

using namespace std;

char w[20];
int an[11][30];
int sn[11];

void table(){
	for(int i = 1; i <= 26; i++)an[1][i] = 1;
	for(int i = 2; i <= 10; i++){
		for(int j = 1; j <= 27-i; j++){
			an[i][j] = 0;
			for(int k = 1; k <= j; k++)an[i][j] += an[i-1][k];
		}
	}
	for(int i = 1; i <= 10; i++){
		sn[i] = 0;
		for(int j = 1; j <= 27-i; j++)sn[i] += an[i][j];
	}
}

int main(){
	cin>>w;
	table();
	int ans = 0;
	int len = strlen(w);
	for(int i = 1; i < len; i++)if(w[i]<w[i-1]){
		cout<<0;
		return 0;
	}
	for(int i = 1; i < len; i++)ans += sn[i];
	for(int i = len-1; i >= 0; i--){
		if(i==0){
			for(int j = 0; j <= w[i]-'a'-1; j++){
				ans += an[len-i][27-len+i-j];
			}
		}
		else{
			for(int j = w[i-1]-'a'+1; j <= w[i]-'a'-1; j++){
				ans += an[len-i][27-len+i-j];
			}
		}
	}
	cout<<ans+1;
}
总结: 跟poj3252非常像的一道题, 也是要把解分为两部分. 一个长度为n的字符串可以求长度小于n的字符串的Code数的和, 加上长度等于n的在这一字符串前面的Code的数量. 下面分开来讲: 


第一部分, 通过找规律发现: 长度为1的字符串a,b,c...的Code数为1, 看做an=1的数列, 则长度为1的字符串总共有Code数S26=26; 长度为2的字符串ax,bx,cx...中, ax的Code数为S25=25, bx为S24=24..., 令bn=Sn, 则长度为2的字符串总共有Code数T25=b1+b2+...+b25=S1+S2+...+S25. 看到这里懂了吧, 其实字符串长度每增加一位, 就相当于把数列再求一次和, 不同的是长度为1时求和要从1求到26, 长度为2时从1求到25, 依次类推. 所以我们只要先打表求出所有长度的Code数, 之后直接加到答案上就ok了.


第二部分, 举个例子, 对字符串aei, 考虑最后面一位字符i, 在它前面的有从e到i也就是f,g,h这3个字符, 即是上面所述的an数列中的a21,a20,a19; 考虑最后两位字符ei, 在它前面的有bx,cx,dx, 即使上面所述的bn数列中的b25,b24,b23. 这样规律就出来了, 我们只需要在刚才求得的数列中拿出我们需要的数加到答案上就搞定了, 也就是说第二部分所用到的数据全是第一部分的副产物.


最后答案别忘了加1, 因为我们求得的只是所有在输入字符串前面的Code的总数, 不包括输入串.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值