BZOJ 1002 FJOI2007 轮状病毒
1002: [FJOI2007]轮状病毒
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5960 Solved: 3251
[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
HINT
Source
第n项公式f[n]=f[n-1]*3-f[n-2]+2,高精度求即可
#include <bits/stdc++.h> #define ll long long using namespace std; inline int read(){ int x=0;int f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} return x*f; } struct bignum{ int len; int num[1000]; }ans[110],k; inline bignum operator * (bignum x,int y){ bignum z; memset(&z,0,sizeof(z)); for(int i=1;i<=x.len;i++){ z.num[i]+=x.num[i]*y; z.num[i+1]=z.num[i+1]+z.num[i]/10; z.num[i]%=10; } z.len=x.len; if(z.num[x.len+1]) z.len++; return z; } inline void operator += (bignum &x,bignum y){ bignum z; memset(&z,0,sizeof(z)); z.len=max(x.len,y.len); for(int i=1;i<=z.len;i++){ z.num[i]+=x.num[i]+y.num[i]; if(z.num[i]>=10) z.num[i]-=10,z.num[i+1]++; } if(z.num[z.len+1]) z.len++; x=z; } inline void operator -= (bignum &x,bignum y){ bignum z; memset(&z,0,sizeof(z)); for(int i=1;i<=x.len;i++){ z.num[i]+=x.num[i]-y.num[i]; if(z.num[i]<0) z.num[i+1]--,z.num[i]+=10; } if(!z.num[x.len]) z.len=x.len-1; else z.len=x.len; x=z; } void print(bignum x){ for(int i=x.len;i>=1;i--){ cout<<x.num[i]; } cout<<endl; } int main(){ int n=read(); ans[1].len=1;ans[1].num[1]=1;ans[2].len=1;ans[2].num[1]=5; for(int i=3;i<=n;i++){ ans[i].len=1;ans[i].num[1]=2; ans[i]+=ans[i-1]*3; ans[i]-=ans[i-2]; } print(ans[n]); return 0; }