1. 程式人生 > 其它 >斐波那契數列(加強版

斐波那契數列(加強版

高精度、結構體、遞推(以及運算子過載)
  • 這題(指P1255)卡得我挺難受的(指WA,TLE,MLE都出來了)

  • 題目很簡單就是個斐波那契數列

  • 重點是資料範圍\(N<=5000\)這真的不會累死人嗎

  • 這麼大的資料自然該想到用高精度

    以及不能用遞迴(因為存在大量重複運算,\(O(2^n)\)的時間複雜度可不是鬧著玩的)要用遞推

程式分析

  1. 高精度部分

    struct BigNum{
    	int len;
    	int d[20000];
    }A[5];
    
    bool cmp(BigNum a,BigNum b){
    	if(a.len!=b.len) return a.len>b.len;
    	for(int i = 0;i<a.len;i++){
    		if(a.d[i]!=b.d[i]) return a.d[i]>b.d[i];
    	}
    	return true;
    }
    
    BigNum operator+(const BigNum b,const BigNum a){
    	BigNum t;
    	memset(t.d,0,a.len+5);
    	for(int i = 0;i<=b.len;i++){
    		t.d[i] = a.d[i] + b.d[i];
    	}
    	for(int i = 0;i<=b.len;i++){
    		if(t.d[i]>=10){
    			t.d[i] -= 10;
    			t.d[i+1] += 1;
    		}
    	}
    	if(t.d[b.len]!=0){
    		t.len = b.len+1;
    	}else{
    		t.len = b.len;
    	}
    	return t;
    }
    void output(BigNum a){
    	for(int i = a.len-1;i>=0;i--){
    		printf("%d",a.d[i]);
    	}
    }
    

    BigNum只開到5的原因是要用到滾動陣列否則會MLE

    (其實這段沒什麼主要就是把高精加搬過來了)

    以及一個運算子過載

    我個人認為這裡的運算子過載完全可以被替換掉

    BigNum operator+(const BigNum &a,const BigNum &b);
    BigNum add(BigNum a,BigNum b);
    
  2. 遞推部分

    void output(BigNum a){
    	for(int i = a.len-1;i>=0;i--){
    		printf("%d",a.d[i]);
    	}
    }
    
    int main(){
    	int n;
    	scanf("%d",&n);
    	
    	A[1].d[0] = 1;
    	A[1].len = 1;
    	A[2].d[0] = 2;
    	A[2].len = 2;
    	if(n<3){
    		printf("%d",n);
    		return 0;
    	}
    	for(int i = 3;i<=n;i++){
    		A[0] = A[1];
    		A[1] = A[2]; 
    		A[2] = A[0] + A[1];
            //滾動陣列
    	}
    	output(A[2]);
    	return 0;
    }