HDU - 1753
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
思路:小数整数分开计算,先计算小数(注意后导0和全为0情况,例如1.2000000 1.0)。再计算整数(注意前导0和只有0情况),整数输出部分真的是搞死了(需要考虑全面,细节比较多),对于极端情况还是欠考虑,不好设置其中的开关条件
c++版源码:(注释里有我遇到的问题)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=405;
int main(int argc, char** argv) {
char a1[maxn],a2[maxn];
int X1[maxn],Y1[maxn],x[maxn],y[maxn];
int lenx,leny,kx,ky;
int point1,point2;
while(scanf("%s%s",&a1,&a2)!=EOF){
memset(X1,0,sizeof(X1));//a1的整数
memset(Y1,0,sizeof(Y1));//a2的整数
memset(x,0,sizeof(x));// a1的小数
memset(y,0,sizeof(y));// a2的小数
lenx=strlen(a1);
leny=strlen(a2);
kx=lenx;//第一个问题:在找点过程中会出现没有小数点的情况,
//所以一开始要设为在数的末端
for(int i=0;i<lenx;i++){
if(a1[i]=='.'){
kx=i;
break;
}
}
ky=leny;
for(int i=0;i<leny;i++){
if(a2[i]=='.'){
ky=i;
break;
}
}
for(int i=0;i<kx;i++){//整数逆序
X1[i]=a1[kx-1-i]-'0';
}
for(int i=kx+1, j=0;i<lenx;i++,j++){
x[j]=a1[i]-'0';//小数
}
/*for(int i=0;i<lenx-kx-1;i++){
printf("%d",x[i]);
}*/
for(int i=0;i<ky;i++){// 整数逆序
Y1[i]=a2[ky-1-i]-'0';
}
for(int i=ky+1,j=0;i<leny;i++,j++){
y[j]=a2[i]-'0';
}
for(int i=400;i>0;i--){//小数相加因为只有400未所以可以这样加,
//(因为是正序所以要从后往前加) 多了这样就不好了
x[i]+=y[i];
if(x[i]>=10){
x[i]-=10;
x[i-1]++;
}
}
//要看在十分位上的数相加要不要进位(个位)
x[0]+=y[0];
if(x[0]>=10){
x[0]-=10;
X1[0]++;
}
point1=-1;//问题二:可能是没有整数的两个整数相加(150+120)
//所以要 赋值为-1做一个标记
for(int i=400;i>=0;i--){
if(x[i]!=0){
point1=i;
break;
}
}
int len=max(ky,kx);
int i;
for(i=0;i<len;i++){
X1[i]+=Y1[i];
if(X1[i]>=10){
X1[i]-=10;
X1[i+1]++;
}
}
point2=0;
for(int j=i;j>=0;j--){//有整数,并输出
if(X1[j]!=0){
point2=1;
}
if(point2){
printf("%d",X1[j]);
}
}
if(point2==0){//无整数时
printf("0");
}
if(point1!=-1){//有小数时
printf(".");
for(int j=0;j<=point1;j++){
printf("%d",x[j]);
}
}
printf("\n");
}
return 0;
}