算法提高 实数相加
时间限制:1.0s 内存限制:512.0MB
问题描述
计算两个实数相加的结果。
输入的实数满足如下要求: (1) 小数点前的整数部分最多100位,(2) 小数点后的小数部分最多100位.
输入的实数满足如下要求: (1) 小数点前的整数部分最多100位,(2) 小数点后的小数部分最多100位.
输入格式
两行字符串,每行都是一个合法的实数。合法的意思是指: 整数部分的值如果大于零,则最高位数字必定大于零. 如果整数部分的值为零,则整数部分只有一个零. 小数部分尾部可以有任意多的零. 可以没有小数部分, 此时也没有小数点. 如果有小数点, 则至少需要有一位小数部分, 且允许是零.
输出格式
相加结果。注意: 小数部分末尾如果有连续的0, 则它们都是有效数字, 不能舍去. 如果是两个整数相加, 则结果仍为整数而没有小数部分.
样例输入
样例一: 0.0000000000000000000000000000000000000111111111000000000000000000 100000000000000000000000000000000000000000000000000000.0 样例二: 3 4 样例三: 3.9 2 样例四: 1.001 8.99999999999999999999999
样例输出
样例一:
100000000000000000000000000000000000000000000000000000.0000000000000000000000000000000000000111111111000000000000000000
样例二:
7
样例三:
5.9
样例四:
10.00099999999999999999999
懒得写注释了。。
#include<iostream> #include<string> #include<cstring> using namespace std; int main() { string a,b; cin >>a>>b; int alen=a.length(),blen=b.length(),aplen=0,bplen=0; //aplen 小数点前的位数. int i,j,aflag=0,bflag=0,ka=0,kb=0; //ka,kb 小数点后的位数。 for(i=0;i<alen;i++){ if(a[i]=='.') aflag=1; if(a[i]!='.'&&aflag==0) aplen++; if(aflag==1) ka++; } if(ka>1) ka--; for(i=0;i<blen;i++){ if(b[i]=='.') bflag=1; if(b[i]!='.'&&bflag==0) bplen++; if(bflag==1) kb++; } if(kb>1) kb--; if(aplen>bplen){ for(i=0;i<aplen-bplen;i++) b="0"+b; } else{ for(i=0;i<bplen-aplen;i++) a="0"+a; } if(ka>kb){ if(kb==0) b+="."; for(i=0;i<ka-kb;i++) b+="0"; } else{ if(ka==0) a+="."; for(i=0;i<kb-ka;i++) a+="0"; } int len=a.length(); int plen=aplen>bplen?aplen:bplen; //小数点前 的位数。 int k=ka>kb?ka:kb; //小数点后的位数。 int s[k+1]; memset(s,0,sizeof(s)); int w=0; for(i=len-1;i>plen;i--,w++){ s[w]+=(a[i]-'0')+(b[i]-'0'); if(s[w]>9){ s[w+1]++; s[w]-=10; } } if(s[w]==0) w--; int sflag=0; if(s[k]==0) sflag=0; else sflag=1; int ss[plen+1]; memset(ss,0,sizeof(ss)); int ww=0; if(sflag==1) ss[ww]+=1; for(i=len-k-2;i>=0;i--,ww++){ ss[ww]+=(a[i]-'0')+(b[i]-'0'); if(ss[ww]>9){ ss[ww+1]++; ss[ww]-=10; } } if(ss[ww]==0) ww--; for(i=ww;i>=0;i--) cout <<ss[i]; if(aflag||bflag) cout <<"."; for(i=k-1;i>=0;i--) cout <<s[i]; return 0; }