游客 Signup | Login
中文 | En

1805 - A+B Problem IV

acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这个问题给解决了。

Input

包含多组测试数据
每组数据包含两个非负数A,B(可能为小数且位数不大于400)

Output

每组输出数据占一行,输出A+B的结果,结果需要是最简的形式。

Examples

Input

1.9 0.1
0.1 0.9
1.23 2.1
3 4.0

Output

2
1
3.33
7

Solution C

#include <stdio.h>
#include <string.h>
int add(char n1[],char n2[]){
    int d1=strlen(n1),d2=strlen(n2);
    int i=d1>=d2?d1:d2,r=0,t;
    char *s=d1>=d2?n1:n2;
    while(d1--&&d2--){
        r+=n1[d1]+n2[d2]-'0';
        if(r>'9') t=10;
        else t=0;
        s[--i]=r-t;
        r=t/10;
    }
    while(r&&i--){
        s[i]++;
        if(s[i]>'9'){
            s[i]-=10;
            r=1;
        }else r=0;
    }
    return r;
}
int main(){
    char n[2][405];
    while(~scanf("%s %s",n[0],n[1])){
        char na[2][405]={0},nb[2][405]={0},*ptr;
        int i,dot=0,t=0,mi,ni,l[2];
        for(i=0;i<2;i++){
            nb[i][0]='0';nb[i][1]=0;
            ptr=strstr(n[i],".");
            if(ptr){
                dot=ptr-n[i];
                strncpy(na[i],n[i],dot);
                na[i][dot]=0;
                strcpy(nb[i],&n[i][dot+1]);
            }else
                strcpy(na[i],n[i]);
            l[i]=strlen(nb[i]);
        }
        if(l[0]<l[1])
            while(l[0]!=l[1])
                nb[0][l[0]++]='0';
        else
            while(l[0]!=l[1])
                nb[1][l[1]++]='0';
        t=add(nb[0],nb[1]);
        if(t)na[0][strlen(na[0])-1]++;
        t=add(na[0],na[1]);
        if(t)printf("1");
        if(strlen(na[0])>=strlen(na[1]))
            printf("%s",na[0]);
        else
            printf("%s",na[1]);
        for(i=l[0]-1;i>=0;i--)
            if(nb[0][i]=='0')nb[0][i]=0;
            else break;
        t=strlen(nb[0]);
        if(t!=0&&(t!=1||nb[0][0]!='0'))
            printf(".");
        printf("%s\n",nb[0]);
    }
    return 0;
}

Solution C++

#include<cstdio>
#include<cstring>
#define max(a,b) a>b?a:b
struct Num{
    int len,back;//len 为 字符串长度  back 为小数的位数
    char num[800];
}A,B;
void swap(char &a,char  &b){
    char t=a;
    a=b;
    b=t;
}
void Init(Num &a){  //  去除小数末尾的零,但至少有一位小数
    a.len=strlen(a.num);
    char *p=strchr(a.num,'.');
    if(p==NULL){        //如果是整数,补充小数点和一位小数
        a.num[a.len++]='.';
        a.num[a.len++]='0';
        a.back=1;
    }
    else{
        int point_loc=p-a.num;//记录小数点的位置,去除小数末尾的零
        for(int i=a.len-1;i>=point_loc+2;i--){
            if(a.num[i]!='0')
                break;
            a.len--;
        }
        a.back=a.len-1-point_loc;
    }

}
void Reverse(Num &a){
    for(int i=0;i<a.len-1-i;i++)
        swap(a.num[i],a.num[a.len-1-i]);
}
void add(Num &a,Num &b){
    Reverse(a);
    int sub=a.back-b.back;//小数位数的差值
    int max_len=max(b.len+sub,a.len);//两个数中最大的位数
    memset(a.num+a.len,'0',max_len-a.len+1);//反转高位补零。
    for(int i=sub;i<max_len;i++){//模拟每一位相加
        if(a.num[i]=='.')
            continue;
        int b_loc=b.len-1-(i-sub);
        if(b_loc>=0)
            a.num[i]+=b.num[b_loc]-'0';
        if(a.num[i]>'9'){
                a.num[i+1]=='.'?a.num[i+2]++ : a.num[i+1]++;
                a.num[i]-=10;
            }



    }
    int min_loc;//记录小数部分不为零的位置。
    for(min_loc=0;a.num[min_loc]=='0';min_loc++);
    max_len= a.num[max_len]=='0' ? max_len-1 : max_len;//如果最高位有进位 输出。
    min_loc=a.num[min_loc]=='.' ? min_loc+1 : min_loc;//如果小数为只有一个小数点,则不必要输出
    for(int i=max_len;i>=min_loc;i--)
        printf("%c",a.num[i]);
    printf("\n");
}
int main(){
    while(scanf("%s%s",A.num,B.num)!=EOF){
        Init(A);
        Init(B);
        A.back>B.back?add(A,B):add(B,A);

    }
}






Time Limit 1 second
Memory Limit 128 MB
Discuss Stats
上一题 下一题