POJ 1503 大整数

之前做的大整数,都是一位一位操作。

优化方案:压缩方案。

模板: + - *  操作符重载

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
using namespace std;

struct bigint{ // only positive number;
    static const int BASE=100000000;
    static const int WIDTH=8;
    vector<int> s;
    //value
    bigint(long long num=0){ *this = num;}
    bigint operator = (long long num){
        s.clear();
        do{
            s.push_back(num%BASE);
            num/=BASE;
        }while(num>0);
        return *this;
    }
    bigint operator = (const string& str){
        s.clear() ;
        int x,len = (str.length()-1)/WIDTH + 1;
        for(int i=0;i<len;i++){
            int end = str.length() - i*WIDTH;
            int start = max(0,end - WIDTH);
            sscanf(str.substr(start,end-start).c_str(),"%d",&x);
            s.push_back(x);
        }
        return *this;
    }
    //input&output
    friend ostream& operator << (ostream &out, const bigint& x){
        out << x.s.back();
        for(int i=x.s.size()-2;i>=0;i--){
            char buf[20];
            sprintf(buf,"%08d",x.s[i]);
            for(int j=0;j<strlen(buf);j++) out << buf[j];
        }
        return out;
    }
    friend istream& operator >>(istream &in, bigint& x){
        string s;
        if(!(in>>s)) return in;
        x=s;
        return in;
    }
    //compare
    bool operator < (const bigint& b) const {
        if(s.size()!=b.s.size()) return s.size() < b.s.size();
        for(int i=s.size()-1;i>=0;i++) if(s[i]!=b.s[i]) return s[i] < b.s[i];
        return false;//equal
    }
    bool operator > (const bigint& b) const {return b < *this;}
    bool operator <= (const bigint& b) const {return !(b < *this);}
    bool operator >= (const bigint& b) const {return !(*this < b);}
    bool operator != (const bigint& b) const {return b < *this || *this < b;}
    bool operator == (const bigint& b) const {return !(b < *this) && !(*this < b);}
    //calculate
    bigint operator +(const bigint& b) const {
        bigint c;
        c.s.clear();
        for(int i=0,g=0;;i++){
            if(g==0 && i>=s.size() && i>=b.s.size()) break;
            int x=g;
            if(i<s.size()) x+=s[i];
            if(i<b.s.size()) x+=b.s[i];
            c.s.push_back(x%BASE);
            g = x/BASE;
        }
        return c;
    }
    bigint operator +=(const bigint& b){
        *this = *this + b;
        return *this;
    }
    bigint operator -(const bigint& b) const {
        bigint c;
        c.s.clear();
        for(int i=0,g=0;;i++){
            if(g==0 && i>=s.size() && i>=b.s.size()) break;
            int x=g;
            if(i<s.size()) x+=s[i];
            if(i<b.s.size()) x-=b.s[i];
            x+=BASE;
            c.s.push_back(x%BASE);
            g = x/BASE - 1;
        }
        return c;
    }
    bigint operator * (const bigint& b) const {
        bigint c;
        c.s.clear();
        bigint g=0;
        for(int i=0;;i++){
            if(g.s.size()==0 && i>=s.size()+b.s.size()-1) break;
            bigint x;
            x.s.clear() ;
            for(int j=0;j<g.s.size();j++) x.s.push_back(g.s[j]);
            if(i<s.size()+b.s.size()-1){
                for(int j = max(0 , i-(int)s.size()+1);j<=min(i,(int)b.s.size()-1);j++){
                    bigint t = (long long)b.s[j]*s[i-j];
                    x += t;
                }
            }
            c.s.push_back(x.s[0]);
            g.s.clear();
            if(x.s.size()>1) for(int j=1;j<x.s.size();j++) g.s.push_back(x.s[j]);
        }
        return c;
    }
};

int main()
{
    //freopen("in.txt","r",stdin);
    bigint a;
    bigint b = 0;
    bigint sum = 0;

    while(cin>>a) {
        if(a==0)
            break;
        sum +=a;
    }

    cout<< sum <<endl;

    return 0;
}

时间: 2024-11-13 02:16:57

POJ 1503 大整数的相关文章

POJ 1181 大整数是否为素数以及求大整数的质因数-数论-(Miller_rabin+Pollard_rho)

题意:求一个整数是否是素数,如果不是,则输出它最小的质因数. 分析: 判断一个大整数是否为素数用Miller_rabin算法,求一个大整数的所有质因数用Pollard_rho算法.这题就是直接套模板. 另外这里的gcd和pow_mod不能用一般的方式,T了.代码里我注释掉的就是T了的写法. 代码: #include<iostream> #include<cmath> #include<ctime> #include<cstdio> #include<a

poj 2389 大整数乘法

#include<iostream> #include<cstdlib> #include<cstring> using namespace std; int main() { char str1[1000],str2[1000]; cin>>str1>>str2; int sum[1000]; memset(sum,0,sizeof(sum)); int len1 = strlen(str1),len2 = strlen(str2); for(

POJ 2506 Tiling(递推+大整数加法)

http://poj.org/problem?id=2506 题意: 思路:递推.a[i]=a[i-1]+2*a[i-2]. 计算的时候是大整数加法.错了好久,忘记考虑1了...晕倒. 1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 7 int n; 8 char s[255][255]; 9 10

POJ 1001 解题报告 高精度大整数乘法模版

题目是POJ1001 Exponentiation  虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于错误的判断还不够严厉. 对边界情况的讨论其实应该是思维严密的表现,当然这并不能表明我写的一点错误都没有,只是多多分析一下还是很有好处的. #include <iostream> #include <fstream> #include <string> #include &l

POJ 1503 Integer Inquiry

http://poj.org/problem?id=1503 题意:给出n个数,计算和. 思路: 基础的大整数加法题. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include<vector> 7 using namespace std; 8 9 const in

POJ 1503

http://poj.org/problem?id=1503 对于这个题我也是醉了,因为最开始是有学长和我们说过这个题目的,我以为我记得题目是什么意思,也就没看题目,结果按案例去理解题意,结果WA了一晚上,我也是醉醉哒. 最后今天才在discuss发现是我的理解题意错了,改下,就对了.给我一个很大的教训..... 题意很简单,,就是一组大整数的加法而已,终止的标志就是只有一个0输入. 1 #include <stdio.h> 2 #include <string.h> 3 4 ch

高精度计算(一):大整数加法

C/C++中的int 类型能表示的范围是-231~231 – 1.unsigned 类型能表示的范围是 0 ~232 – 1,即 0~4294967295.所以,int 和unsigned 类型变量,都不能保存超过10 位的整数.有时我们需要参与运算的数,可能会远远不止10 位,例如要求100!的精确值.即便使用能表示的很大数值范围的double 变量,但是由于double变量只有64 位,double 变量的精度也不足以表示一个超过100 位的整数.一般我们称这种基本数据类型无法表示的整数为大

poj 2992 Divisors 整数分解

设m=C(n,k)=n!/((n-k)!*k!) 问题:求m的因数的个数 将m分解质因数得到 p1有a1个 p2有a2个 .... 由于每个质因数可以取0~ai个(全部取0就是1,全部取ai就是m)最后的答案就是(a1+1)*(a2+1)*....* 注意不能直接将m分解,因为太大,所以要先分解n,n-k,k,根据他们再来加减. #include <iostream> #include <cstdio> #include <cmath> #include<cstr

高精度计算(四):大整数乘法(采用“万进制”)

[例1]大整数乘法. 编写一个程序,求两个不超过200 位的非负整数的积. (1)编程思路. 大整数乘大整数,实质就是在小学竖式乘法的基础上枚举各个乘数位与被乘数相乘,累加到结果当中.其中乘数中的第j位与被乘数中的第i位相乘时,结果应该保存到结果的第i+j-1位中. (2)源程序. #include <iostream>using namespace std;const int base=10000;const int maxlen=50+2;void charTobignum(char *c