1002: [FJOI2007]轮状病毒
轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示
N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不
同的3轮状病毒,如下图所示
现给定n(N<=100),编程计算有多少个不同的n轮状病毒
Input
第一行有1个正整数n
Output
计算出的不同的n轮状病毒数输出
Sample Input
3
Sample Output
16
递推式是f[i]=3* f[i-1]-f[i-2]+2 数据有点大,就需要高精,高精我还写的半天,真是太弱了;
#include<bits/stdc++.h>
using namespace std;
struct BigInt{
int data[500],len;
BigInt(){this->len =0;memset(this->data,0,sizeof(this->data));}
BigInt operator + (int b){
BigInt ret;
ret.len = this->len?this->len:1;
for(int i=1;i<=this->len;i++){
ret.data[i]=this->data[i];
}
ret.data[1]+=b;b=1;
while(ret.data[b] >= 10){
ret.data[b+1]+=ret.data[b]/10;
ret.data[b]%=10;
b++;
ret.len = max(ret.len,b);
}
return ret;
}
BigInt operator - (BigInt b){
BigInt ret;ret.len = this->len;
for(int i=this->len;i>=1;i--){
ret.data[i] = this->data[i] - b.data[i];
int p=i;
while(ret.data[p] < 0){
ret.data[p]+=10;
ret.data[p+1]-=1;
p++;
}
}
while(ret.data[ret.len] == 0){
ret.len--;
}
return ret;
}
BigInt operator * (int mtn){
BigInt ret;ret.len = this->len;
for(int i=this->len;i>=1;i--){
ret.data[i]=this->data[i] * mtn;
int p = i;
while(ret.data[p] >= 10){
ret.data[p+1]+=ret.data[p]/10;
ret.data[p]%=10;
p++;
ret.len= max(ret.len,p);
}
}
return ret;
}
void print(){
for(int i=this->len;i>=1;i--){
printf("%d",this->data[i]);
}
putchar('\n');
}
};
BigInt a,b;
int main(){
int n;
scanf("%d",&n);
a=a+1;b=b+5;
if(n==1)a.print();
if(n==2)b.print();
else{
for(int i=3;i<=n;i++){
BigInt cc;
cc=b*3;
cc=cc-a;
cc=cc+2;
a=b;b=cc;
}
b.print();
}
return 0;
}