HDU2065 红色病毒
Problem Description
医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色病毒",经研究发现,该病毒及其变种的DNA的一条单链中,胞嘧啶,腺嘧啶均是成对出现的。
现在有一长度为N的字符串,满足一下条件:
(1) 字符串仅由A,B,C,D四个字母组成;
(2) A出现偶数次(也可以不出现);
(3) C出现偶数次(也可以不出现);
计算满足条件的字符串个数.
当N=2时,所有满足条件的字符串有如下6个:BB,BD,DB,DD,AA,CC.
由于这个数据肯能非常庞大,你只要给出最后两位数字即可.
Input
每组输入的第一行是一个整数T,表示测试实例的个数,下面是T行数据,每行一个整数N(1<=N<2^64),当T=0时结束.
Output
对于每个测试实例,输出字符串个数的最后两位,每组输出后跟一个空行.
Sample Input
4 1 4 20 11 3 14 24 6 0
Sample Output
Case 1: 2
Case 2: 72
Case 3: 32
Case 4: 0
Case 1: 56
Case 2: 72
Case 3: 56
来源:HDU2065
题目分析
由题目信息可知,影响这个字符串是否合法(符合题意)根本在于A数量的奇偶和C数量的奇偶。
若字符串不做任何限制条件,长度为n的字符串对于每一位都有ABCD四种可能,所以长度为n且不做任何限制条件的字符串应该有4n 种。
在这4n种情况中可以分为四大类:
1:字符串中有偶数个A和偶数个C。
2:字符串中有奇数个A和偶数个C。
3:字符串中有偶数个A和奇数个C。
4:字符串种有奇数个A和奇数个C。
对于上述的四种情况设以下四类F[ ][ ]。
不妨设 :
F[n][0]为长度为n的合法字符串(A和C都是偶数个)的个数。
F[n][1]为长度为n,A出现次数为奇数,C出现的次数为偶数这样的字符串的个数。
F[n][2]为长度为n,C出现次数为奇数,A出现的次数为偶数这样的字符串的个数。
F[n][3]为长度为n,A出现次数为奇数,C出现次数也为奇数这样的字符串的个数。
可以得到F[n][0]=2F[n-1][0]+F[n-1][1]+F[n-1][2]
这个式子是怎么得到的呢?
2F[n-1][0]的意思是长度为n-1的合法字符串的个数,要把这些字符串变为长度为n的合法字符串,只需要在原字符串中添加B或者D这两种无关元素,也就是有两种添加方法,故为2F[n-1][0]
F[n-1][1]的意思是长度为n-1的A为奇数个,C为偶数个的字符串的个数,只需要在源字符串中添加1个A即可是字符串变为合法字符串。即 F[n-1][1]
F[n-1][2]的意思是长度为n-1的A为偶数个,C为奇数个的字符串的个数,只需要在源字符串中添加1个C即可是字符串变为合法字符串。即 F[n-1][2]
故 可以得到这样的式子F[n][0]=2F[n-1][0]+F[n-1][1]+F[n-1][2]
同样的思考方法,不难得出以下式子:
- F[n][0]=2F[n-1][0]+F[n-1][1]+F[n-1][2]
- F[n][1]=2F[n-1][1]+F[n-1][0]+F[n-1][3]
- F[n][2]=2F[n-1][2]+F[n-1][0]+F[n-1][3]
- F[n][3]=2F[n-1][3]+F[n-1][1]+F[n-1][2]
- 由于4n种情况可分为四大类 ,同样可以列出这样的式子:F[n][0]+F[n][1]+F[n][2]+F[n][3]=4n
联立1234式(1式+4式=2式+3式)可得 - F[n][0]+F[n][3]=F[n][1]+F[n][2]
联立5和6式可得 F[n][0]+F[n][3]=22n-1
我们需要求的是F[n][0].因此要想办法消掉F[n][3]
根据题意不难发现,A和C具有等地位,又由于其对称性可得:
F[n][1]=F[n][2] —7
故联立7,5,6,1可得:
2F[n-1][0]+22n-3=F[n][0]
对于此通项公式的求法可利用线性递归数列的通常解法
对于22n-3不妨设其通项时为2w
那么即可得到 2(F[n-1][0]-2w)=F[n][0]-2w+2
通过待定系数法 ,不难得到 w+1=2n-3。 因此w=2n-4
所以可以求得通向为F[n][0]-22n-2=2n-1
因此F[n][0]=2n-1+(2n-1)2.
题目中让用后两位来表示结果,不妨寻找一下2t取余100后的规律:
20%100= 1
21%100= 2
22%100= 4
23%100= 8
24%100=16
25 %100= 32
26 %100= 64
27 %100=28
28 %100=56
29%100=12
210%100=24
211%100=48
212%100=96
213%100=92
214%100=84
215%100=68
216%100=36
217%100=72
218%100=44
219%100=88
220%100=76
221%100=52
222%100=4
观察以上结果可得知:只有在t=0,1不符合规律,也就是n=1,2时不符合规律,对于n>=3时,二十个一次循环。
因而对于任何n,只需要先减去2后对20取余即可,找出对应位次的后两位的值,再利用后两位值的平方加上后两位的值对于这个整体再次%100取余后两位即可。
下面是代码实现
#include <stdio.h>
#include <math.h>
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int sum;
int a[25]= {0,4,8,16,32,64,28,56,12,24,48,96,92,84,68,36,72,44,88,76,52};
if(n==1)
{
sum=2;
}
else if(n==2)
{
sum=6;
}
else
{
int temp=a[(n-2)%20];
sum=(temp+temp*temp)%100;
}
printf("%d",sum);
}
return 0;
}