1002: [FJOI2007]轮状病毒

Time Limit: 1 Sec  Memory Limit: 162 MB

Description

给定n(N<=100),编程计算有多少个不同的n轮状病毒。

Input

第一行有1个正整数n。

Output

将编程计算出的不同的n轮状病毒数输出

Sample Input

3

Sample Output

16
 
这道题看上去就很不(wei)错(suo),而且摆在第2题,BBG在路过时跟我说这个要用基尔霍夫矩阵,瞬间吓尿导致我颓了好久不敢刷BZOJ。
后来我偶然看到这道题,觉得定有蹊跷,所以我也用了相应的正(e)当(xin)的解法:
我首先把n为1到7时的结果算出来,然后找规律,发现F(n)=3F(n1)F(n2)+2,F(1)=1,F(2)=5.
然后加上高精度,喜闻乐见AC了。
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int n,as,bs,cs,a[10000],b[10000],c[10000];
void aa()
 {
    int i,j,k,l,q,w,e=0;
    memset(c,0,sizeof(c));
    cs=bs;
    c[1]=2;
    for (i=1;i<=bs;i++)
     {
        c[i]+=3*b[i]+e;
        e=c[i]/10;
        c[i]%=10;
     }
    while (e>0)
     {
        cs++;
        c[cs]=e%10;
        e/=10;
     }
    for (i=1;i<=cs;i++)
     {
        c[i]=c[i]-a[i];
        if (c[i]<0) 
         {
            c[i]+=10;
            c[i+1]--;
         }
     }
    while (c[cs]==0) cs--;
    as=bs;
    for (i=1;i<=as;i++) a[i]=b[i];
    bs=cs;
    for (i=1;i<=bs;i++) b[i]=c[i];
 }
int main()
 {
    int i,j,k,l,q,w,e;
    scanf("%d",&n);
    if (n==1)
     {
        printf("%d\n",1);
        return 0;
     }else
    if (n==2)
     {
        printf("%d\n",5);
        return 0;
     }
    as=1;bs=1;
    a[1]=1;b[1]=5;
    for (i=3;i<=n;i++)
      aa();
    for (i=cs;i>=1;i--)
      printf("%d",c[i]);
    printf("\n");
    return 0;
 }