1002: [FJOI2007]轮状病毒
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4057 Solved: 2237
[ Submit][ Status][ Discuss]
Description
轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示
N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不
同的3轮状病毒,如下图所示
现给定n(N<=100),编程计算有多少个不同的n轮状病毒
Input
第一行有1个正整数n
Output
计算出的不同的n轮状病毒数输出
Sample Input
3
Sample Output
16
【题解】【结论题,递推式:Fn=3*F(n-1)-F(n-2)+2,虽然范围很小,但要用高精】
[没有看懂解析的窝用结论水过233~]
【解析见:点击打开链接】
<span style="font-size:14px;">#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f1[210],l1,f2[210],l2,t[210],len,n;
inline long long do1()
{
long long F1=5,F2=1,t=0;
if(n==1) return 1;
if(n==2) return 5;
for(int i=3;i<=n;++i)
{
t=F1; F1=F1+F1+F1;
F1-=F2; F1+=2;
F2=t;
}
return F1;
}
inline void ch()
{
for(int i=1;i<=l1;++i)
f1[i]*=3,f1[i]+=f1[i-1]/10,f1[i-1]%=10;
if(f1[l1]>=10) f1[++l1]=f1[l1-1]/10,f1[l1-1]%=10;
return;
}
inline void add()
{
int l=max(l1,l2),i;
int sum[210];
memset(sum,0,sizeof(sum));
if(f2[1]>=2||l2==1) f2[1]-=2;
else
{
for(i=1;i<=l2;++i)
{
if(i==1)
{f2[i+1]-=1; f2[i]+=10; f2[i]-=2; continue; }
if(i!=1&&f2[i]>=0) break;
f2[i+1]-=1; f2[i]+=10;
}
while(!f2[l2]) l2--;
}
for(i=1;i<=l;++i)
if(f1[i]>=f2[i]) sum[i]=f1[i]-f2[i];
else
f1[i+1]-=1,f1[i]+=10,sum[i]=f1[i]-f2[i];
while(!sum[l]) l--;
l1=l;
for(i=1;i<=l1;++i) f1[i]=sum[i];
return;
}
int main()
{
int i,j;
scanf("%d",&n);
if(n<=45)
{long long ans=do1(); printf("%lld\n",ans); return 0;}
f1[++l1]=5; f2[++l2]=1;
for(i=3;i<=n;++i)
{
len=l1;
for(j=1;j<=len;++j) t[j]=f1[j];
ch();
add();
l2=len;
for(j=1;j<=l2;++j) f2[j]=t[j];
}
for(i=l1;i>0;i--)
printf("%d",f1[i]);
return 0;
}</span>