您的位置:首页 > 其它

HDU 2065 红色病毒

2015-10-05 18:39 211 查看
题目地址:HDU2065

思路:

A C A C A C

奇偶 + 奇奇 = 奇__

偶奇 + 偶偶 = 偶__

设A(偶)C(偶) 的方法数为g(n)

则:

g(n)=AC(偶偶) + AC(偶偶) +AC(奇偶) +AC(偶奇)

由于对称可知:AC(奇偶)=AC(偶奇)

故:

g(n)=2*AC(偶__)

令AC(偶__)=f(n) 则g(n)=2*f(n-1)

下面讨论f(n):

f(n)=AC(奇) +AC (偶)*3

=2*f(n-1)+4^(n-1)

综上可得:g(n)=2*g(n-1)+2^(2*n-3)

利用迭代可以算出:

g(n)=2^(n-1)+2^(2*n-2)

由于题目上要求1<=N<2^64 是非常大的数 long long 也不可能将其完全保存下来,于是考虑找末两位的规律:

因为题目只要求输出最后2位数,我们依次输出2的n的最后两位看看…

20 -> 1

21 -> 2

22 -> 4

23 -> 8

24 -> 16

25 -> 32

26 -> 64

27 -> 28

28 -> 56

29 -> 12

210 -> 24

211 -> 48

212 -> 96

213 -> 92

214 -> 84

215 -> 68

216 -> 36

217 -> 72

218 -> 44

219 -> 88

220 -> 76

221 -> 52

222 -> 4

到了222时,末尾2位又变成4,与22一样,这时候就进入了一个循环了(每20个一次循环)。

所以,结果只能是这22个中的一个。只有n=0 和 n=1是需要特殊考虑的。其他n就等于2(n-2) % 20 + 2的值了。

Code:

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;

int main()
{
int t;
int d[]={4,8,16,32,64,28,56,12,24,48,96,92,84,68,36,72,44,88,76,52};
while(cin>>t&&t)
{
long long n;
int i=0;
while(t--)
{
cin>>n;
int temp;
if(n==1) temp=2;
else if(n==2) temp=6;
else temp=(d[(n-3)%20]+d[(2*n-4)%20])%100;
printf("Case %d: %d\n",++i,temp);
}
cout<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: