大明A+B

题目来自杭电:http://acm.hdu.edu.cn/showproblem.php?pid=1753
大明A+B

Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10214 Accepted Submission(s): 3662

Problem Description
话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫“大明”。
这时他已经不是那个只会做100以内加法的那个“小明”了,现在他甚至会任意长度的正小数的加法。

现在,给你两个正的小数A和B,你的任务是代表大明计算出A+B的值。

Input
本题目包含多组测试数据,请处理到文件结束。
每一组测试数据在一行里面包含两个长度不大于400的正小数A和B。

Output
请在一行里面输出输出A+B的值,请输出最简形式。详细要求请见Sample Output。

Sample Input
1.1 2.9
1.1111111111 2.3444323343
1 1.1

Sample Output
4
3.4555434454
2.1

代码:

#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
const int MAX = 400;
char a[MAX * 2],b[MAX * 2];
char _a[MAX],a_[MAX];
char _b[MAX],b_[MAX];
int _sum[MAX],sum_[MAX];

//反转
int change(char *a)
{
    int len = strlen(a);
    int i;
    char temp;


    for(i = 0; i < len/2; i++)
    {
        temp = a[i];
        a[i] = a[len - 1 - i];
        a[len - 1 - i] = temp;
    }
    return 0;
}

int main()
{
    //ofstream cout("out.txt");
    int i,j;
    int len1,len2;
    int t1,t2;
    int carry;
    int size_;

    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    while(cin >> a >> b)
    {
        carry = 0;

        memset(_a,0,sizeof(_a));
        memset(a_,0,sizeof(a_));
        memset(_b,0,sizeof(_b));
        memset(b_,0,sizeof(b_));
        memset(sum_,0,sizeof(sum_));
        memset(_sum,0,sizeof(_sum));

        i = 0;
        j = 0;
        while(a[i])
        {
            if(a[i] == '.')
                break;
            _a[j++] = a[i++];
        }

        _a[j] = '\0';
        change(_a);

        i++;
        j = 0;
        while(a[i])
            a_[j++] = a[i++];

        a_[j] = '\0';
        change(a_);

        i = 0;
        j = 0;
        while(b[i])
        {
            if(b[i] == '.')
                break;
            _b[j++] = b[i++];
        }

        _b[j] = '\0';
        change(_b);

        i++;
        j = 0;
        while(b[i])
            b_[j++] = b[i++];

        b_[j] = '\0';
        change(b_);

        //小数部分
        len1 = strlen(a_);
        len2 = strlen(b_);
        size_ = len1 > len2 ? len1 : len2;

        if(len1 < len2)
        {
            i = 0;
            while(i < len2 - len1)
                sum_[i] = b_[i++] - '0';


            carry = 0;
            for(j = 0; j < len1 || i < len2; j++)
            {
                t1 = a_[j] - '0';
                t2 = b_[i] - '0';

                t1 = t1 + t2 + carry;
                sum_[i++] = t1 % 10;
                carry = t1 / 10;
            }
            sum_[i] = '\0';
            if(i > len2)
                carry= sum_[i - 1];

        }
        else
        {
            i = 0;
            while(i < len1 - len2)
                sum_[i] = a_[i++] - '0';

            carry = 0;
            for(j = 0; j < len2 || i < len1; j++)
            {
                t1 = b_[j] - '0';
                t2 = a_[i] - '0';

                t1 = t1 + t2 +carry;
                sum_[i++] = t1 % 10;
                carry = t1 / 10;
            }
            sum_[i] = '\0';
            if(i > len1)
                carry = sum_[i - 1];
        }

        //整数部分
        len1 = strlen(_a);
        len2 = strlen(_b);

        i = 0;
        while(1){
            if(i > len1 && i > len2)
                break;
                if(i >= len1)
                    t1 = 0;
                else
                    t1 = _a[i] - '0';
                if(i >= len2)
                    t2 = 0;
                else
                    t2 = _b[i] - '0';
                t1 = t1 + t2 + carry;
                _sum[i] = t1 % 10;
                carry = t1 / 10;
            i++;
        }

        //输出
        if(carry)
            cout << carry;
            j = i - 1;
            while(j >= 0){
                if(_sum[j])
                    break;
                j--;
            }
            if(j == -1)
                cout << "0";

        for(; j >= 0; j--)
            cout << _sum[j];

        int head = 0;
        while(head < size_)
        {
            if(sum_[head])
                break;
            head++;
        }

        if(head < size_)
        {
            cout << ".";
            for(i = size_ - 1; i >= head; i--)
                cout << sum_[i];
        }
        cout << endl;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
    }
    return 0;
}

小结:
大数问题,思路是将数字分解为整数部分和小数部分,分别处理,考虑进位问题和前导0和后导0,附一些参考样例
1.1 2.9
1.1111111111 2.3444323343
1 1.1
1.00000000000003 .43
34345.34 32425345
8523400000 777.700
3435 4554
0.000 0.0000
99999 1
1.0001 2.9999
1.235262578623 2.29375824758243527200
23546756.345326547567454 .2142356754225653425346

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值