1. 程式人生 > >BZOJ 1002 - 輪狀病毒 - [基爾霍夫矩陣(待補)+高精度][FJOI2007]

BZOJ 1002 - 輪狀病毒 - [基爾霍夫矩陣(待補)+高精度][FJOI2007]

() out strlen esp lean 例如 計算 stream height

題目鏈接:https://www.lydsy.com/JudgeOnline/problem.php?id=1002

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[i] = f[i-1] \times 3 - f[i-2] + 2$。

題解:

#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
 
struct BigInt
{
    static const int maxdigit=100;
    int len,d[maxn];
 
    void clean(){while(len>1 && !d[len-1]) len--;}
    string str()const
    {
        string
s; for(int i=0;i<len;i++) s+=d[len-1-i]+0; return s; } BigInt(){memset(d,0,sizeof(d));len=1;} BigInt(int num){*this=num;} BigInt(char* num){*this=num;} bool operator<(const BigInt& oth)const { if(len!=oth.len) return len<oth.len;
for(int i=len-1;i>=0;i--) if(d[i]!=oth.d[i]) return d[i]<oth.d[i]; return false; } bool operator>(const BigInt& oth)const{return oth<*this;} bool operator<=(const BigInt& oth)const{return !(oth<*this);} bool operator>=(const BigInt& oth)const{return !(*this<oth);} bool operator!=(const BigInt& oth)const{return oth<*this || *this<oth;} bool operator==(const BigInt& oth)const{return !(oth<*this) && !(*this<oth);} BigInt operator=(const char* num) { memset(d,0,sizeof(d)); len=strlen(num); for(int i=0;i<len;i++) d[i]=num[len-1-i]-0; clean(); return *this; } BigInt operator=(int num) { char s[20]; sprintf(s,"%d",num); return *this=s; } BigInt operator+(const BigInt& oth)const { BigInt c; c.len=max(len,oth.len); for(int i=0;i<=c.len;i++) c.d[i]=0; for(int i=0;i<c.len;i++) { c.d[i]+=(i<len?d[i]:0)+(i<oth.len?oth.d[i]:0); c.d[i+1]+=c.d[i]/10; c.d[i]%=10; } c.len+=(c.d[c.len]>0); c.clean(); return c; } BigInt operator-(const BigInt& oth)const { BigInt c=*this; if(c<oth) printf("Produce negative number!\n"); int i; for(i=0;i<oth.len;i++) { c.d[i]-=oth.d[i]; if(c.d[i]<0) c.d[i]+=10, c.d[i+1]--; } while(c.d[i]<0) c.d[i++]+=10, c.d[i]--; c.clean(); return c; } BigInt operator*(const BigInt& oth)const { BigInt c; for(int i=0;i<len;i++) for(int j=0;j<oth.len;j++) c.d[i+j]+=d[i]*oth.d[j]; for(int i=0;i<len+oth.len || !c.d[i];c.len=++i) c.d[i+1]+=c.d[i]/10, c.d[i]%=10; c.clean(); return c; } BigInt operator/(const BigInt& oth)const { BigInt c=*this, r=0; for(int i=0;i<len;i++) { r=r*10+c.d[len-1-i]; int j; for(j=0;j<10;j++) if(r<oth*(j+1)) break; c.d[len-1-i]=j; r=r-oth*j; } c.clean(); return c; } BigInt operator%(const BigInt& oth) { BigInt r=0; for(int i=0;i<len;i++) { r=r*10+d[len-1-i]; int j; for(j=0;j<10;j++) if(r<oth*(j+1)) break; r=r-oth*j; } return r; } BigInt operator+=(const BigInt& oth) { *this=*this+oth; return *this; } BigInt operator*=(const BigInt& oth) { *this=*this*oth; return *this; } BigInt operator-=(const BigInt& oth) { *this=*this-oth; return *this; } BigInt operator/=(const BigInt& oth) { *this=*this/oth; return *this; } }; istream& operator>>(istream& in, BigInt& x) { string s; in>>s; x=s.c_str(); return in; } ostream& operator<<(ostream& out,const BigInt& x) { out<<x.str(); return out; } int n; BigInt f[maxn]; int main() { cin>>n; f[1]=1; f[2]=5; for(int i=3;i<=n;i++) f[i]=(f[i-1]*3-f[i-2]+2); cout<<f[n]<<endl; }

BZOJ 1002 - 輪狀病毒 - [基爾霍夫矩陣(待補)+高精度][FJOI2007]