【New deal】poj2033 Alphacode
好久不写点东西了,博客里都长草了XD~
今天发道水题先练练手…
题目是poj的2033(http://poj.org/problem?id=2033),一道很水的动归。题目如下。
【题目描述】
一对valentine聚在一起,商讨用一种加密方法传递信息以避免学校发现。
Girl说,我们就用这样一种传统的方法,A对应1,B对应2,这样我们的话就变成了一个数串,想法如何?
Boy说,你真笨~就拿“Te amo”来说,按照你的办法翻译成20511315,这样我可能想成“Tekco”或者“Teaacae”,我怎么知道你说的是什么?就别的数串来说,答案可能成千上万。Girl不信,她要给你一个数串,让你算算一共有多少种答案。
【输入格式】
输入可能有多个数据,每组数据以换行隔开,文件以一个0结束。(关于这里更准确的信息请参见原题)
【输出格式】
对于每个数据输出相应的答案数,以换行隔开。
【样例输入】
25114
1111111111
3333333333
0
【样例输出】
6
89
1
这题是一道很显然的DP。用f[i]记录到i位的答案数,从左到右按位进行计算:
1. 串长为1,答案数为1。
否则:
2. 如果这一位为0,那么f[i]=f[i-2],因为它和s[i-1]只能构成一种情况。
3. 如果这一位不为0,则令k=s[i-1]*10+s[i],如果k∈[1,26]则f[i]=f[i-1]+f[i-2],因为s[i]既可以自己作为一个一位数,也可以和s[i-1]作为一个两位数出现;反之,f[i]=f[i-1],因为 它只能自己的构成一个一位数。
4. f[length(s)]即为解。
思路很简单,但是我的Pascal代码就是过不去…因为解可能很大,在长度到一定值的时候f数组中的值就会出问题。这种情况在c++上也会出现,但是c++的代码就过了…
我不知道是Pascal和c++的代码在读入的时候不一样还是在越界的处理上不一样,如果你知道为什么,请联系我,不胜感激~
注意:1. 单个数据的长度可能超过一行。
2. 最好用64位存储…
3.最好用c编写…
下面附上两段代码。
未过代码(Pascal):
program poj2033; var f:array[0..50000]of longint; s:ansistring; procedure dynamicp(x:longint); var i,j:longint; k:integer; begin if x=1 then begin writeln('1'); exit; end; if x=2 then begin if s[2]<>'0' then writeln('2') else writeln('1'); exit; end; f[0]:=1; f[1]:=1; for i:=2 to x do begin if s[i]='0' then f[i]:=f[i-2] else begin k:=(ord(s[i-1])-ord('0'))*10+ord(s[i])-ord('0'); if (k>0)and(k<27) then f[i]:=f[i-2]+f[i-1] else f[i]:=f[i-1]; end; end; writeln(f[x]:0:0); end; begin readln(s); while s<>'0' do begin dynamicp(length(s)); readln(s); end; end.
参考代码(c++,来源:http://blog.sina.com.cn/s/blog_6635898a0100h9rn.html):
#include <iostream> using namespace std; const int MAXN = 50000; int main() { __int64 dp[MAXN]; char s[MAXN]; while(scanf("%s", s + 1) != EOF) { int len = strlen(s + 1); if(len == 1 && s[1] == '0') break; dp[0] = dp[1] = 1; for(int i = 2; i <= len; i++) { if(s[i] != '0') { dp[i] = dp[i - 1]; int num = (s[i - 1] - '0') * 10 + (s[i] - '0'); if(num >= 11 && num <= 26) dp[i] += dp[i - 2]; }else{ if(s[i - 1] == '0') dp[i] == dp[i - 1]; else if(s[i - 1] == '1' || s[i - 1] == '2') dp[i] = dp[i - 2]; } } printf("%I64d\n", dp[len]); } return(0); }
本文地址:http://www.cnblogs.com/saltless/archive/2011/05/29/2061959.html
(Saltless原创,转载请注明出处)