Project Euler 013 Large sum

题意:求 10 50 位数的和的前 10 位。
分析:裸的高精度,或者double啊啥的应该也是能过的吧。

#include <bits/stdc++.h>

#define ll long long

#define pii std::pair<int,int>
#define mp std::make_pair
#define fi first
#define se second

#define SZ(x) (int)(x).size()
#define pb push_back

template<class T>inline void chkmax(T &x, const T &y) {if(x < y) x = y;}
template<class T>inline void chkmin(T &x, const T &y) {if(x > y) x = y;}

template<class T>
inline void read(T &x) {
    char c;int f = 1;x = 0;
    while(((c=getchar()) < '0' || c > '9') && c != '-');
    if(c == '-') f = -1;else x = c-'0';
    while((c=getchar()) >= '0' && c <= '9') x = x*10+c-'0';
    x *= f;
}
static int outn;
static char out[(int)2e7];
template<class T>
inline void write(T x) {
    if(x < 0) out[outn++] = '-', x = -x;
    if(x) {
        static int tmpn;
        static char tmp[20];
        tmpn = 0;
        while(x) tmp[tmpn++] = x%10+'0', x /= 10;
        while(tmpn) out[outn++] = tmp[--tmpn];
    }
    else out[outn++] = '0';
}

namespace BigInteger {
#define clr(a, b) memset(a, b, sizeof a)
#define rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define per(i, a, b) for(int i = (a); i >= (b); --i)
    const int MAX = 100, M = 10;
    struct Bignum
    {
        int a[MAX];
        Bignum() 
        {
            clr(a, 0);
            a[0] = 1;
        }
        Bignum(int k)
        {
            clr(a, 0);
            a[0] = 1;
            if(k)
                {
                    a[0] = 0;
                    while(k)
                        {
                            a[++a[0]] = k%M;
                            k /= M;
                        }
                }
        }
        Bignum& operator = (const Bignum &b)
        {
            clr(a, 0);
            memcpy(a, b.a, (b.a[0]+1)*sizeof(int));
            return *this;
        }
        inline void read()
        {
            char str[MAX] = "\0";
            scanf("%s", str);
            a[0] = strlen(str);
            per(i, a[0], 1)
                a[a[0]-i+1] = str[i-1]-'0';
        }
        inline void adjust()
        {
            rep(i, 1, a[0])
                {
                    while(a[i] < 0) a[i+1]--, a[i] += M;
                    while(a[i] >= M) a[i+1]++, a[i] -= M; 
                }
            while(a[a[0]+1]) a[0]++;
            while(a[0] > 1 && !a[a[0]]) a[0]--;
        }
        inline void write()
        {
            per(i, a[0], 1)
                putchar(a[i] + '0');
        }
    };

    inline bool operator < (const Bignum &a, const Bignum &b)
    {
        if(a.a[0] != b.a[0]) return a.a[0] < b.a[0];
        per(i, a.a[0], 1)
                                             if(a.a[i] != b.a[i])
                                                 return a.a[i] < b.a[i];
        return false;
    }

    inline bool operator == (const Bignum &a, const Bignum &b)
    {
        if(a.a[0] != b.a[0]) return false;
        rep(i, 1, a.a[0])
            if(a.a[i] != b.a[i])
                return false;
        return true;
    } 

    inline bool operator > (const Bignum &a, const Bignum &b)
    {
        if(a.a[0] != b.a[0]) return a.a[0] > b.a[0];
        per(i, a.a[0], 1)
            if(a.a[i] != b.a[i])
                return a.a[i] > b.a[i];
        return false;
    }

    inline bool operator <= (const Bignum &a, const Bignum &b)
    {
        return !(a > b);
    }

    inline bool operator >= (const Bignum &a, const Bignum &b)
    {
        return !(a < b);
    }

    inline Bignum operator + (const Bignum &a, const Bignum &b)
    {
        Bignum ret;
        int len = std::max(a.a[0], b.a[0]);
        rep(i, 1, len)
            ret.a[i] = a.a[i]+b.a[i];
        ret.a[0] = len;
        ret.adjust();
        return ret;
    }

    inline void operator += (Bignum &a, const Bignum &b)
    {
        a = a+b;
    }

    inline Bignum operator - (const Bignum &a, const Bignum &b)
    {
        Bignum ret;
        int len = a.a[0];
        rep(i, 1, len)
            ret.a[i] = a.a[i]-b.a[i];
        ret.a[0] = len;
        ret.adjust();
        return ret;
    }

    inline void operator -= (Bignum &a, const Bignum &b)
    {
        a = a-b;
    }

    inline Bignum operator * (const Bignum &a, int k)
    {
        Bignum ret;
        ret.a[0] = a.a[0];
        rep(i, 1, a.a[0])
            ret.a[i] = a.a[i]*k;
        ret.adjust();
        return ret;
    }

    inline Bignum operator * (const Bignum &a, const Bignum &b)
    {
        Bignum ret;
        per(i, a.a[0], 1)
            ret = ret*M+b*a.a[i];
        return ret;
    }

    template<class T>
    inline void operator *= (Bignum &a, const T &b)
    {
        a = a*b;
    }

    inline Bignum operator / (const Bignum &a, const Bignum &b)
    {
        Bignum ret, tmp;
        ret.a[0] = a.a[0];
        per(i, a.a[0], 1)
            {
                tmp = tmp*M+a.a[i];
                int l = 0, r = 9;
                while(l < r)
                    {
                        int mid = (l+r+1)>>1;
                        if(b*mid > tmp) r = mid-1;
                        else l = mid;
                    }
                tmp -= b*l;
                ret.a[i] = l;
            }
        ret.adjust();
        return ret;
    }

    inline Bignum operator % (const Bignum &a, const Bignum &b)
    {
        return a-a/b*b;
    }
    void solve() {
        Bignum a[100], sum;
        for(int i = 0; i < 100; ++i) a[i].read();
        for(int i = 0; i < 100; ++i) sum += a[i];
        sum.write();
    }
}

int main() {
    BigInteger::solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值