bzoj1002[FJOI2007]轮状病毒

题目传送门
ly大神告诉我这是一道水题,然而看题看了半天愣是看不出咋做……于是无奈叹息,和神犇的差距已经这么大了么……谦虚地去问大神是啥算法,大神说:“这道题我是看题解的,其实我也不会……”果断泪奔……去看hzwer——真正的大牛的博客以后,终于找到了答案,这是基尔霍夫矩阵,用递归来实现。还没崇拜玩这让人那啥一阵的名字,也还没来的及去%论文,后边括号里那几个字就让我崩溃了:“我也不知道是什么”。这都啥题啊!!!这都啥人啊!!!!!只好直接套公式1A走人……
Description
  轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示
bzoj1002[FJOI2007]轮状病毒_第1张图片
  N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不同的3轮状病毒,如下图所示
bzoj1002[FJOI2007]轮状病毒_第2张图片
  现给定n(N<=100),编程计算有多少个不同的n轮状病毒
Input
  第一行有1个正整数n
Output
  计算出的不同的n轮状病毒数输出
Sample Input
3
Sample Output
16
直接上公式f[i]=(f[i-1]*3-f[i-2]+2)(没错你没猜错这就是复制的……)

//制作人:陈保良
#include
#include
using namespace std;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
struct node
{
    int len,a[110];
    node(){len=0;memset(a,0,sizeof(a));}
}f[110];
node jianfa_h(node n1,node n2)
{
    n1.a[1]+=2;
    node n0;
    n0.len=n1.len;
    for(int i=1;i<=n0.len;i++)n0.a[i]=n1.a[i]-n2.a[i];
    for(int i=1;i<=n0.len;i++)
        if(n0.a[i]<0)
        {
            n0.a[i+1]--;
            n0.a[i]+=10;
        }
    int i=n0.len;
    while(n0.a[i]==0 && i>1)i--;
    n0.len=i;
    return n0;
}
node chengfa_x_h(node n1)
{
    node n0;
    n0.len=n1.len;
    for(int i=1;i<=n0.len;i++)n0.a[i]=n1.a[i]*3;
    for(int i=1;i<=n0.len;i++)
    {
        n0.a[i+1]+=n0.a[i]/10;
        n0.a[i]%=10;
    }
    int i=n0.len;
    while(n0.a[i+1]>0)
    {
        i++;
        n0.a[i+1]+=n0.a[i]/10;
        n0.a[i]%=10;
    }
    n0.len=i;
    return n0;
}
int main()
{
    int n;
    n=read();
    f[1].len=f[2].len=1;
    f[1].a[1]=1;f[2].a[1]=5;
    for(int i=3;i<=n;i++)f[i]=jianfa_h(chengfa_x_h(f[i-1]),f[i-2]);
    for(int i=f[n].len;i>=1;i--)printf("%d",f[n].a[i]);
    printf("\n");
    return 0;
}

第一次写这种明明自己不懂却定义为水题的题解,相信以后会越来越多的……

你可能感兴趣的:(bzoj,递归,高精度,基尔霍夫矩阵)