http://acm.hdu.edu.cn/showproblem.php?pid=1753
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
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
Problem solving report:
Description: 求两个大位正小数的相加和。
Problem solving: 通过找小数点把输入的每一个数据分成整数部分和小数部分(要考虑到只有整数部分的情况),我们再将整数部分右对齐,采用倒序相加,小数部分如此。小数部分相加的时候,要把位数在后面加“0”保证两个小数部分的位数相同(这个一开始把数组全部重置为0就行了),然后再加,还要考虑小数部分的进位情况,最后输出的时候要把小数部分的“0”去掉。
#include <stdio.h>
#include <string.h>
#define MAX(a, b) (a > b) ? a : b
int main()
{
char a[410], b[410];
int lena, lenb, len, k1, k2, k, p;
int i, j, a1[410], a2[410], b1[410], b2[410];
while (~scanf("%s%s", a, b))
{
memset(a1, 0, sizeof(a1));
memset(a2, 0, sizeof(a2));
memset(b1, 0, sizeof(b1));
memset(b2, 0, sizeof(b2));
k1 = lena = strlen(a);
k2 = lenb = strlen(b);
for (i = 0; i < lena; i++)
{
if (a[i] == '.')
{
k1 = i;
break;
}
}
for (j = 0; j < lenb; j++)
{
if (b[j] == '.')
{
k2 = j;
break;
}
}
for (i = k1 - 1; i >= 0; i--)
a1[k1 - i - 1] = a[i] - '0';
for (j = k2 - 1; j >= 0; j--)
b1[k2 - j - 1] = b[j] - '0';
for (i = k1 + 1; i < lena; i++)
a2[i - k1 - 1] = a[i] - '0';
for (j = k2 + 1; j < lenb; j++)
b2[j - k2 - 1] = b[j] - '0';
k = MAX(lena - k1 - 1, lenb - k2 - 1);
for (i = k - 1; i > 0; i--)
{
a2[i] += b2[i];
if (a2[i] > 9)
{
a2[i] -= 10;
a2[i - 1]++;
}
}
a2[0] += b2[0];
if (a2[0] > 9)
{
a2[0] -= 10;
a1[0]++;
}
p = k;
for (i = k - 1; i >= 0; i--)
{
if (a2[i])
{
p = i;
break;
}
}
len = MAX(k1, k2);
for (i = 0; i < len; i++)
{
a1[i] += b1[i];
if (a1[i] > 9)
{
a1[i] -= 10;
a1[i + 1]++;
}
}
for (i = len; i >= 0; i--)
{
if (!(i - len) && !a1[len])
continue;
printf("%d", a1[i]);
}
if (p != k)
{
printf(".");
for (i = 0; i <= p; i++)
printf("%d", a2[i]);
}
printf("\n");
}
return 0;
}