您的位置:首页 > 其它

BZOJ1002: [FJOI2007]轮状病毒

2017-09-29 18:56 369 查看
Description

  轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子

和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示



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

同的3轮状病毒,如下图所示



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

Input

  第一行有1个正整数n

Output

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

Sample Input

3

Sample Output

16

题目传送门

填坑!填神坑!

这道题好神奇啊!

如果不是手推+网上博客,我还真搞不定这个东西!

打表如下:

1 5 16 45 121 320 841 2205 5776 15125 39601 103680 271441 710645 1860496。

很快先发现一个规律:第1、3、5、7位是平方数,2、4、6、8位除以5后也是平方数。

然后再整理: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,3,8,21,55。。。。。。然后…然后就没有然后了

可是,我看了蒋神博客,蒋神云:这不是斐波那契的一半吗:1,2,3,5,8,13,21,24,55.。。。。。另外一个也能表示成类似的相加的数列:

奇数位:1 3 4 7 11 18 29 76

偶数位:1 2 3 5 8 13 21 34 55

然后高精度解决

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
unsigned  long  f[110],len;
char st[511];
struct node
{
int len,a[511];
node()
{
len=0;
memset(a,0,sizeof(a));
}
}ff[110];
node jianfa(node n1,node n2)
{
node no;
no.len=n1.len;
for(int i=1;i<=no.len;i++) no.a[i]=n1.a[i]-n2.a[i];
for(int i=1;i<=no.len;i++)
{
if(no.a[i]<0)
{
no.a[i+1]--;
no.a[i]+=10;
}
}
while(no.a[no.len]==0 && no.len>1 ) no.len--;
return no;
}
node chengfa(node n1)
{
int i,j;
node no;
no.len=n1.len;
for(i=1;i<=n1.len;i++)
no.a[i]+=n1.a[i]*3;
for(i=1;i<=no.len;i++)
{
no.a[i+1]+=no.a[i]/10;
no.a[i]%=10;
}
i=no.len;
while(no.a[i+1]>0)
{
i++;
no.a[i+1]+=no.a[i]/10;
no.a[i]%=10;
}
no.len=i;
while(no.a[no.len]==0&&no.len>1)no.len--;
return no;
}
node jiafa(node n1)
{
node no;
int i,j;
no.len=n1.len;
for(int i=1;i<=no.len;i++)no.a[i]=n1.a[i];
no.a[1]+=2;
i=no.len;
for(i=1;i<=no.len;i++)
{
no.a[i+1]+=no.a[i]/10;
no.a[i]%=10;
}
while(no.a[i+1]>0)
{
i++;
no.a[i+1]=no.a[i]/10;
no.a[i]%=10;
}
no.len=i;
while(no.a[no.len]==0&&no.len>1)no.len--;
return no;
}
int main()
{
int n;
scanf("%d",&n);
ff[1].len=1;ff[1].a[1]=1;ff[2].len=1;ff[2].a[1]=5;
for(int i=3;i<=n;i++)
{
ff[i]=chengfa(ff[i-1]);
ff[i]=jianfa(ff[i],ff[i-2]);
ff[i]=jiafa(ff[i]);
}
for(int i=ff
.len;i>=1;i--) printf("%d",ff
.a[i]);
printf("\n");
return 0;
}


by_lmy
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: