BZOJ1002: [FJOI2007]轮状病毒

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 7798  Solved: 4233
Description

  轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示

  N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不
同的3轮状病毒,如下图所示

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

Input

  第一行有1个正整数n

Output 

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

Sample Input

3

Sample Output

16


f[n]=3∗f[n−1]−f[n−2]+2

  

/**************************************************************

    Problem: 1002

    User: ictsing

    Language: C++

    Result: Accepted

    Time:0 ms

    Memory:1292 kb

****************************************************************/

 

//求轮状病毒,类似于生成树一样的东西

/*

首先暴搜,然后打表发现规律

命令行编辑的时候手抽代码都不见了,重新写一遍吧QAQ

1

5

16

45

121

320

841

2205

5776

15125

39601

103680

271441

 

1*1

          5*1*1   

4*4     

          5*3*3    

11*11    

          5*8*8     

29*29     

          5*21*21     

76*76     

          5*55*55     

199*199     

          5*144*144     

521*521

 

1 (1) 2 (3) 5 (8) 13 (21) 34 (55) 89 (144)

(1) 3 (4) 7 (11) 18 (29) 47 (76) 123 (199) 322 (521)

大概就是类似于斐波那契数一样的加就可以了

高精度搞一搞233333

*/

/*

#include <iostream>

#include <cstdio>

using namespace std;

const int mt = 100+5;

struct edge{

  int l,r;

}e[mt];

int n;

int f[mt],tmp[mt];

int getfa(int x)

{

  if(f[x]==x) return x;

  return f[x]=getfa(f[x]);

}

int ans;

bool flag[mt];

void dfs(int x,int ed)

{

  if(x==n+1) {ans++;return ;}

  int tmp[mt];

  for(int i=ed+1;i<=n*2;i++)

    if(!flag[i])

  {

    int a=getfa(e[i].l);

    int b=getfa(e[i].r);

        if(a==b) continue;

        for(int j=0;j<=n;j++) tmp[j]=f[j];

        f[a]=b,flag[i]=true,dfs(x+1,i);

        for(int j=0;j<=n;j++) f[j]=tmp[j];

        flag[i]=false;

  }

}

int main()

{

  for(n=1;n<=15;n++)

  {

      ans=0;

      for(int i=1;i<n;i++)

       e[i].l=i,e[i].r=i+1;

       e[n].l=n,e[n].r=1;

      for(int i=n+1;i<=n+n;i++)

       e[i].l=0,e[i].r=i-n;

     for(int i=0;i<=n;i++) f[i]=i;

      dfs(1,0);

      printf("%d\n",ans);

  }

  return 0;

}

*/

#include <iostream>

#include <cstdio>

#include <cstring>

using namespace std;

const int mt =50+1;

struct arr{

  int num,p[mt];

}a,b,c;

arr add(arr a,arr b)

{

  arr c;memset(c.p,0,sizeof(c.p));

  c.num=max(a.num,b.num);

  for(int i=1;i<=c.num;i++)

    c.p[i]=a.p[i]+b.p[i];

  for(int i=1;i<=c.num;i++)

    c.p[i+1]+=c.p[i]/10,c.p[i]%=10;

  if(c.p[c.num+1]) c.num++;

  return c;

}

arr multi(arr a,arr b)

{

  arr c;memset(c.p,0,sizeof(c.p));

  for(int i=1;i<=a.num;i++)

    for(int j=1;j<=b.num;j++)

      c.p[i+j-1]+=a.p[i]*b.p[j];

    c.num=a.num+b.num-1;

    for(int i=1;i<=c.num;i++)

      c.p[i+1]+=c.p[i]/10,c.p[i]%=10;

    while(c.p[c.num+1])

      c.num++,c.p[c.num+1]+=c.p[c.num]/10,c.p[c.num]%=10;

    return c;

}

inline int read()

{

  int num=0,flag=1;

  char ch;

  do{

    ch=getchar();

    if(ch=='-') flag=-1;

  }while(ch<'0'||ch>'9');

  do{

    num=num*10+ch-'0';

    ch=getchar();

  }while(ch>='0'&&ch<='9');

  return num*flag;

}

int main()

{

  int n=read();

  if(n==0) puts("0");

  else if(n==1) puts("1");

  else if(n==2) puts("5");

  else if(n&1)

  {

    a.p[1]=1;b.p[1]=3;a.num=1;b.num=1;  

    for (int i=3;i<=n;i++)  

    {  

      c=add(a,b);  

      a.num=b.num;for (int j=1;j<=a.num;j++) a.p[j]=b.p[j];  

      b.num=c.num;for (int j=1;j<=b.num;j++) b.p[j]=c.p[j];  

    }  

    c=multi(c,c);  

    for (int i=c.num;i>0;i--)  

      printf("%d",c.p[i]);  

  }

  else

  {

    a.p[1]=1,b.p[1]=2,a.num=1,b.num=1;

    for(int i=4;i<=n;i++)

    {

      c=add(a,b);

      a.num=b.num;for(int j=1;j<=a.num;j++) a.p[j]=b.p[j];

      b.num=c.num;for(int j=1;j<=b.num;j++) b.p[j]=c.p[j];

    }

    c=multi(c,c);

    memset(a.p,0,sizeof(a.p));a.p[1]=5,a.num=1;c=multi(c,a);

    for(int i=c.num;i>0;i--)

      printf("%d",c.p[i]);

  }

  return 0;

}

 

评论

热度(4)