/*
大明A+B
话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫“大明”。
这时他已经不是那个只会做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 <cstring>
char s1[410];
char s2[410];
int a1[410*2];
int b1[410*2];
int res[410*2];
void init()
{
memset(a1,0,sizeof(a1));
memset(b1,0,sizeof(b1));
memset(res,0,sizeof(res));
}
void Create(char *s,int *a)
{
int i,j,k;
int len = strlen(s);
if(strchr(s,'.')==NULL)//没有找到点
{
k = len;
}
else
{
k = strchr(s,'.') - s; //找到小数点位置
}
for(i=k-1,j=400;i>=0;i--,j++)//存入小数
{
a[j] = s[i] - '0';
}
for(i=k+1,j=399;i<len;i++,j--)//存入整数
{
a[j] = s[i] - '0';
}
}
void Carry_Over()//大数的进位计算
{
int i,v = 0,t;
for(i=0;i<805;i++)
{
t = a1[i] + b1[i] + v;
res[i] = t % 10;
v = t / 10;
}
}
void Print_All()
{
int i = 805;
while(res[i] ==0 && i>=400)//去掉小数方向的第一个不为零之前的0;
{
i--;
}
int j = 0;
while(res[j] ==0 && j<400)//去掉整数方向的第一个不为零之前的0;
{
j++;
}
if(i==399 && j==400)//整数和小数都为零了 输出0;
{
printf("0\n");
}
else
{
for(;i>=400;i--)
{
printf("%d",res[i]);
}
if(j!=400) //判断小数点后面是否有小数,有则输出小数点 ,无则不输出
{
printf(".");
for(i=399;i>=j;i--)
{
printf("%d",res[i]);
}
}
printf("\n");
}
}
int main()
{
while(scanf("%s %s",&s1,&s2)!=EOF)
{
init();
Create(s1,a1);
Create(s2,b1);
Carry_Over();
Print_All();
}
return 0;
}
大明A+B
话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫“大明”。
这时他已经不是那个只会做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
*/
思路:看到这一道题你不会觉得特别难,只是太麻烦,可能会想到用小数点将数据分成两个大数进行计算,这也是一种方法 ,不过太过于麻烦,接下来我所说的是一种相对上面简便一点的方法,首先题目上面既然说明位数不会超过400,那我们为什么不定义一个800+的数组,就算全是整数或者全是小数, 我们也完全能将它放入数组 ;首先依旧需要判断小数点的位置,然后标记后,这样剩下的数就成为一个完整的大整数,这样我们就比较容易进行计算,我们将数组的[400]作为对照点,a1[0]--a1[399]存放整数,a[401]----a[800]存放小数,b1[410]也同样按照这样操作 ,将数据放入数组中,s1->a1,s2->b1,这样整数小数各个位上都是对照的,剩下的进行补零,然后就是大数之间的计算,在最后输出的时候,需要判定下是否为零,同样在输出i=400的时候小数点的存在是否要输出 ,,(详见程序)
#include <cstring>
char s1[410];
char s2[410];
int a1[410*2];
int b1[410*2];
int res[410*2];
void init()
{
memset(a1,0,sizeof(a1));
memset(b1,0,sizeof(b1));
memset(res,0,sizeof(res));
}
void Create(char *s,int *a)
{
int i,j,k;
int len = strlen(s);
if(strchr(s,'.')==NULL)//没有找到点
{
k = len;
}
else
{
k = strchr(s,'.') - s; //找到小数点位置
}
for(i=k-1,j=400;i>=0;i--,j++)//存入小数
{
a[j] = s[i] - '0';
}
for(i=k+1,j=399;i<len;i++,j--)//存入整数
{
a[j] = s[i] - '0';
}
}
void Carry_Over()//大数的进位计算
{
int i,v = 0,t;
for(i=0;i<805;i++)
{
t = a1[i] + b1[i] + v;
res[i] = t % 10;
v = t / 10;
}
}
void Print_All()
{
int i = 805;
while(res[i] ==0 && i>=400)//去掉小数方向的第一个不为零之前的0;
{
i--;
}
int j = 0;
while(res[j] ==0 && j<400)//去掉整数方向的第一个不为零之前的0;
{
j++;
}
if(i==399 && j==400)//整数和小数都为零了 输出0;
{
printf("0\n");
}
else
{
for(;i>=400;i--)
{
printf("%d",res[i]);
}
if(j!=400) //判断小数点后面是否有小数,有则输出小数点 ,无则不输出
{
printf(".");
for(i=399;i>=j;i--)
{
printf("%d",res[i]);
}
}
printf("\n");
}
}
int main()
{
while(scanf("%s %s",&s1,&s2)!=EOF)
{
init();
Create(s1,a1);
Create(s2,b1);
Carry_Over();
Print_All();
}
return 0;
}