最近发现一种新病毒,因为其蔓延速度与最近在Internet上传播的“红色 代码 ”不相上下,所以被称作“红色病毒”。经研究发现,该病毒及其变种的DNA的一条单链中,胞嘧啶、腺嘌呤均是成对出现的。为了搞清楚该病毒的特征,你要对此做出研究。你要得到的是在这个特征下,可能成为病毒的DNA单链序列的个数。更精确的说,你要统计所有满足下列条件的长度为n的字符串的个数: 1.字符串仅右A,T,C,G组成。 2.A出现偶数次,或者不出现。 3.C出现偶数次,或者不出现。 例如,当n=2时,满足条件的字符串有如下6个: TT,TG,GT,CG,AA,CC。 这个数可能非常大,所以只需输出最后两位数字。 输入: redvirus.in 输入文件每行给出一个n,1<=n<=10^9,最后以0结束。 输出: 对每个n,输出满足条件的字符串个数的最后两位数字。 输入样例: 1 2 3 100 0 输出样例: 2 6 20 32 限时: 每个n限时5秒。 注意:n的取值很大,不能直接使用递推法。
---------------------------------------------------------------------------------------------------------------------------------------------
下面是解题思路: 令 f(i) 字符串长度为i时,A,C的个数都为偶数的字符串的个数。 (A) g(i) 字符串长度为i时,A,C的个数都为奇数的字符串的个数。 (B) h(i) 字符串长度为i时,A,C的个数一个为奇数,另一个为偶数的字符串的个数。 (C) 显然,有: f(i)+g(i)+h(i)=4^i (1) 根据题意,有 f(1)=2 g(1)=0 h(1)=2 递推: i) n=1时,f(1)=1,g(1)=0,h(1)=2 ii) n=n+1时,有 f(n)=f(n-1)*2+h(n-1) g(n)=g(n-1)*2+h(n-1) 解释如下: 任意一个长度为n-1的、符合条件(A)的字符串加上一个T或者G即可构成一个长度为n的、符合条件(A)的字符串。所以有f(n-1)*2。 任意一个长度为n-1的、符合条件(B)的字符串加上A,C中个数为奇数的字符集可构成一个长度为n的、符合条件(A)的字符串。所以有h(n-1)。 g(n)的构造方法也一样。 由(1)得 h(n)=4^n-f(n)-g(n) 所以 h(n)=4^n-f(n-1)*2-g(n-1)*2-h(n-1)*2 =4^n-2*(f(n-1)+g(n-1)+h(n-1)) =4^n-2*4^(n-1) =2*4^(n-1) 代入,得 f(n)=f(n-1)*2+2*4^(n-2) =2f(n-1)+2^(2n-3) f(n+1)=2f(n)+2^(2n-1) 为a(n+1)=pa(n)+q(n)形式的递推式,求通项公式,得 f(n)=2^n+2^(2n-2)-2^(n-1) =2^(n-1)+2^(2n-2) 将2^k的后两位val(k)列表 k 1 2 3 4 5 6 7 8 9 10 val 02 04 08 16 32 64 28 56 12 24 k 11 12 13 14 15 16 17 18 19 20 val 48 96 92 84 68 36 72 44 88 76 k 21 22 val 52 04 因为val(k)=2*val(k-1) mod 100,又因为val(2)=val(22),所以val的值在val(2)以后以20为周期循环。 所以,有 val(1)=2 val(k)=val((k-2) mod 20+2) (k>1) 实现: CONST pow2 : array [ 2 .. 21 ] of byte = ( 4, 8, 16, 32, 64, 28, 56, 12, 24, 48, 96, 92, 84, 68, 36, 72, 44, 88, 76, 52 ); Function pow_two( n : longint ) : byte { 计算2^n的后两位 } Begin if n = 1 then begin pow_two := 2; exit; end; pow_two := pow2[ ( n - 2 ) mod 20 + 2 ]; End; 然后根据上述公式计算即可。