题目来自杭电: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