UVA 465 Overflow 高精度加法和乘法运算

来源:互联网 发布:致得软件 编辑:程序博客网 时间:2024/06/13 20:38

题目给出多组数据,判断输入的两个数是否超出 int 型变量的取值范围,并判断最终计算结果是否超出 int 取值范围


这里先给出我自己最初写的AC代码:


思路:

用两个string来储存输入的数,将他们与 int 的最大值比较大小,然后求出他们的和或者是积来判断其与int最大值的大小关系


Result  :  Accepted   Memory  :  0 KB   Time  :  15 ms

/* * Author: Gatevin * Created Time:  2014/7/3 16:54:43 * File Name: test.cpp */#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>using namespace std;const double eps(1e-8);typedef long long lint;string s1,s2,ans;bool check(string s)//判断其与int最大值的关系{    bool zero = true;    for(int i = 0; i < s.length(); i++)//找到s的起始位,以为之前加法和乘法运算有将s反向过,现在反向回来会有前导零    {        if(s[i] != '0')        {            zero = false;            break;        }    }    if(zero) return false;//如果zero = 0,则说明 s = "0"    int flags = 0;    for(int i = 0; i < s.length(); i++)    {        if(s[i] != '0')        {            flags = i;            break;        }    }    int lens = s.length() - flags;    string tmp;    if(sizeof(int)*8 == 32)    {        tmp = "2147483647";    }    else    {        tmp = "32767";    }    int lenm = tmp.length();    if(lens > lenm)    {        return true;    }    if(lens < lenm)    {        return false;    }    for(int i = flags, j = 0; i <= s.length() - 1 && j <= tmp.length() - 1; i++,j++)    {        if(s[i] > tmp[j])        {            return true;        }        if(s[i] < tmp[j])        {            return false;        }    }    return false;}void judge(string ss1, string ss2, char op){    bool res;    if(op == '*')    {        string ans(ss1.length() + ss2.length() + 1, '0');//乘法运算        reverse(ss1.begin(), ss1.end());        reverse(ss2.begin(), ss2.end());        int c;        for(int i = 0; i < ss1.length(); i++)        {            c = 0;            for(int j = 0; j < ss2.length(); j++)            {                /*                 * 理由参照 刚写的 UVA 10106 的题解                 */                int tmp1 = ((ans[i + j] - '0') + c + (ss1[i] - '0')*(ss2[j] - '0')) /10;                int tmp2 = ((ans[i + j] - '0') + c + (ss1[i] - '0')*(ss2[j] - '0')) % 10;                ans[i + j] = tmp2 + '0';                c = tmp1;            }            ans[i + ss2.length()] += c;        }        reverse(ans.begin(), ans.end());        res = check(ans);    }    else    {        string ans(max(ss1.length(), ss2.length()) + 1,'0');        reverse(ss1.begin(), ss1.end());        reverse(ss2.begin(), ss2.end());        int c = 0;        if(ss1.length() >= ss2.length())//模拟加法        {            for(int i = 0; i < ss2.length(); i++)            {                ans[i] = (ss1[i] - '0' + ss2[i] - '0' + c) % 10 + '0';                c =  (ss1[i] - '0' + ss2[i] - '0' + c) / 10;            }            for(int j = ss2.length(); j < ss1.length(); j++)            {                ans[j] = (ss1[j] - '0' + c) % 10 + '0';                c = (ss1[j] - '0' + c) /10;            }            ans[ss1.length()] += c;//小心最后的进位        }        else        {            for(int i = 0; i < ss1.length(); i++)            {                ans[i] = (ss2[i] - '0' + ss1[i] - '0' + c) % 10 + '0';                c =  (ss2[i] - '0' + ss1[i] - '0' + c) / 10;            }            for(int j = ss1.length(); j < ss2.length(); j++)            {                ans[j] = (ss2[j] - '0' + c) % 10 + '0';                c = (ss2[j] - '0' + c) /10;            }            ans[ss2.length()] += c;        }        reverse(ans.begin(), ans.end());        res = check(ans);    }    if(res)    {        cout<<"result too big"<<endl;    }}int main(){    char mid;    while(cin>>s1>>mid>>s2)    {        bool c1 = check(s1);        bool c2 = check(s2);        cout<<s1<<" "<<mid<<" "<<s2<<endl;        if(c1)        {            cout<<"first number too big"<<endl;        }        if(c2)        {            cout<<"second number too big"<<endl;        }        judge(s1,s2,mid);    }    return 0;}



然后是套用模板写的代码:


Result  : Accepted    Memory  : 0 KB   Time  :  15 ms


/* * Author: Gatevin * Created Time:  2014/7/4 12:58:26 * File Name: test.cpp */#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>using namespace std;const double eps(1e-8);typedef long long lint;struct bign{    int len,s[1000];    bign()    {        len = 0;        memset(s, 0 ,sizeof(s));    }        bign operator = (const char* num)    {        len = strlen(num);        for(int i = 0; i < len; i++)        {            s[i] = num[len - i - 1] - '0';        }        return *this;    }        bign operator = (int num)    {        char s[1000];        sprintf(s, "%d", num);        *this = s;        return *this;    }        bign(int num)    {        *this = num;    }        bign(const char* num)    {        *this = num;    }        string str() const    {        string res = "";        for(int i = 0; i < len; i++)        {            res = (char)(s[i] + '0') + res;        }        if(res == "")        {            res = "0";        }        return res;    }        bign operator + (const bign& b) const    {        bign c;        c.len = 0;        for(int i = 0, g = 0; g || i < max(len, b.len); i++)        {            int x = g;            if(i < len) x += s[i];            if(i < b.len) x += b.s[i];            c.s[c.len++] = x % 10;            g = x / 10;        }        return c;    }        bign operator * (const bign& b) const    {        bign c;        c.len = len + b.len;        int k;        for(int i = 0; i < len; i++)        {            k = 0;            for(int j = 0; j < b.len; j++)            {                int tmp1 = (s[i] * b.s[j] + k + c.s[i + j]) / 10;                int tmp2 = (s[i] * b.s[j] + k + c.s[i + j]) % 10;                c.s[i + j] = tmp2;                k = tmp1;            }            c.s[i + b.len] += k;        }        while(c.len > 1)        {            if(c.s[c.len - 1] == 0)            {                c.len--;            }            else            {                break;            }        }        return c;    }    bign operator += (const bign& b)    {        *this = *this + b;        return *this;    }        bool operator < (const bign& b) const    {        if(len != b.len) return len < b.len;        for(int i = len - 1; i >= 0; i--)        {            if(s[i] != b.s[i])            {                return s[i] < b.s[i];            }        }        return false;    }};    istream& operator >> (istream &in, bign & x)    {        string s;        in >> s;        x = s.c_str();        return in;    }        ostream& operator << (ostream & out, const bign& x)    {        out << x.str();        return out;    }int main(){    bign x1,x2;    char op;    bign max_int = (1 << (sizeof(int)*8 - 1)) - 1;   while(cin>>x1>>op>>x2)   {       cout<<x1<<" "<<op<<" "<<x2<<endl;              while(x1.len > 1)//处理数据输入可能是有前导零的情况       {           if(x1.s[x1.len - 1] == 0)           {               x1.len--;           }           else           {               break;           }       }              while(x2.len > 1)       {           if(x2.s[x2.len - 1] == 0)           {               x2.len--;           }           else           {               break;           }       }              if(max_int < x1)       {           cout<<"first number too big"<<endl;       }       if(max_int < x2)       {           cout<<"second number too big"<<endl;       }       if(op == '+')       {           if(max_int < x1 + x2)           {               cout<<"result too big"<<endl;           }       }       if(op == '*')       {           if(max_int < x1*x2)           {               cout<<"result too big"<<endl;           }       }   }   return 0;}



0 0