【洛谷 1255】 数楼梯

思路

不难发现答案就是斐波那契数列,要用到高精度。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int p = 10000;
struct _int{
    int num[1000], len;
    _int(){memset(num,0,sizeof num); len = 0;}
    void __int(){memset(num,0,sizeof num); len = 0;}
    void operator = (int tt){
        __int();
        for(;tt;tt/=p) num[++len] = tt%p;
        len ++;
        while(len > 1 && !num[len]) len --;
    }
    void operator = (const char ch[]){
        __int();
        int ll = strlen(ch);
        for(int i = ll-1; i >= 0; i -= 4){
            int tmp = 0, st = i-3;
            st = max(st, 0); 
            for(int j = st; j <= i; j ++)
                tmp = tmp * 10 + ch[j]-'0';
            num[++len] = tmp;
        }
        len ++;
        while(len > 1 && !num[len]) len --;
    }
    _int operator * (const _int tt)const{
        _int ans;
        for(int i = 1; i <= len; i ++)
            for(int j = 1; j <= tt.len; j ++)
                ans.num[i+j-1] += num[i]*tt.num[j];
        ans.len = len+tt.len-1;
        for(int i = 1; i < ans.len; i ++)
            if(ans.num[i]/p) ans.num[i+1] += ans.num[i]/p, ans.num[i]%=p;
        while(ans.num[ans.len]/p) ans.num[ans.len+1] += ans.num[ans.len]/p, ans.num[ans.len++]%=p;
        ans.len ++;
        while(ans.len > 1 && !ans.num[ans.len]) ans.len --;
        return ans;
    }
    _int operator + (const _int tt) const{
        _int ans;
        ans.len = max(len, tt.len);
        for(int i = 1; i <= ans.len; i ++)
            ans.num[i] = num[i] + tt.num[i];
        for(int i = 1; i < ans.len; i ++)
            if(ans.num[i]/p) ans.num[i+1] += ans.num[i]/p, ans.num[i]%=p;
        while(ans.num[ans.len]/p) ans.num[ans.len+1] += ans.num[ans.len]/p, ans.num[ans.len++]%=p;
        ans.len ++;
        while(ans.len > 1 && !ans.num[ans.len]) ans.len --;
        return ans;
    }
    void print(){
        printf("%d", num[len]);
        for(int i = len-1, ll; i >= 1; i --){
            if(num[i] != 0) ll = (int)(log(num[i])/log(10)) + 1;
            else ll = 1;
            for(int j = 1; j <= 4-ll; j ++) printf("0");
            printf("%d", num[i]);
        }
    }

};
int main(){
    _int a, b, c;
    int n;
    scanf("%d", &n);
    if(n == 0) printf("0");
    else if(n == 1) printf("1");
    else if(n == 2) printf("1");
    if(n <= 2) return 0;
    a = 1, b = 1;
    for(int i = 3; i <= n+1; i ++){
        c = a+b;
        a = b, b = c;
    }
    c.print();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值