原文链接: A+B Problem IV 大实数加法
上一篇: A-B Problem 大数相等
下一篇: 求高精度幂 (未完成)
A+B Problem IV
http://acm.nyist.net/JudgeOnline/problem.php?pid=513
时间限制:1000 ms | 内存限制:65535 KB
难度:3
输入
包含多组测试数据
每组数据包含两个正数A,B(可能为小数且位数不大于400)
输出
每组输出数据占一行,输出A+B的结果,结果需要是最简的形式。
样例输入
1.9 0.1 0.1 0.9 1.23 2.1 3 4.0
样例输出
2 1 3.33 7
描述
acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这个问题给解决了。
我的代码
#include
#include
#define MAX 1000
char a[MAX], b[MAX], c[MAX];
//处理化简数字 000.0100 --> 0.01
void deal(char *s) {
int len, i, t, k, dot;
// .1 --> 0.1
if (s[0] == '.') {
len = strlen(s);
for (i = len + 1; i > 0; i--)
s[i] = s[i - 1];
s[0] = '0';
}
//去除整数前导零
for (i = 0; s[i] && s[i] == '0' && s[i + 1] && s[i + 1] != '.'; i++);
//左移 i 位
if (i > 0) {
for (k = 0; s[k + i]; k++)
s[k] = s[k + i];
s[k] = '\0';
}
//去除小数后面的 0
for (dot = 0; s[dot] && s[dot] != '.'; dot++);
len = strlen(s);
for (i = len - 1; i > dot && s[i] == '0'; i--);
s[i + 1] = '\0';
if (s[i] == '.') s[i] = '\0';
}
int main(int argc, char *argv[]) {
int lena, lenb, lenc, t, d, i, j, k, dota, dotb, dotc;
while (scanf("%s %s", a, b) != EOF) {
deal(a);
deal(b);
// printf("%s %s\n", a, b);
//加法
lena = strlen(a);
lenb = strlen(b);
lenc = 0;
d = 0; //进位
for (dota = 0; a[dota] && a[dota] != '.'; dota++);
for (dotb = 0; b[dotb] && b[dotb] != '.'; dotb++);
i = lena - 1;
j = lenb - 1;
// i, j 分别指向 a, b
while (i >= 0 && j >= 0) {
if (i > dota && j > dotb) {
//小数部分
if (i - dota == j - dotb) {
t = a[i--] + b[j--] - 2 * '0' + d;
} else if (i - dota > j - dotb) {
t = a[i--] + d - '0';
} else if (i - dota < j - dotb) {
t = b[j--] - '0' + d;
}
if (t > 9) {
d = 1;
c[lenc++] = t % 10 + '0';
} else {
d = 0;
c[lenc++] = t + '0';
}
} else if (i < dota && j < dotb) {
//整数部分
if (i - dota == j - dotb) {
t = a[i--] + b[j--] - 2 * '0' + d;
} else if (i - dota < j - dotb) {
t = a[i--] + d - '0';
} else if (i - dota > j - dotb) {
t = b[j--] - '0' + d;
}
if (t > 9) {
d = 1;
c[lenc++] = t % 10 + '0';
} else {
d = 0;
c[lenc++] = t + '0';
}
} else if (i == dota && j == dotb) {
//小数点
c[lenc++] = '.';
i--; j--;
} else if (i == dota && j != dotb) {
//小数点
c[lenc++] = '.';
i--;
} else if (i != dota && j == dotb) {
//小数点
c[lenc++] = '.';
j--;
} else if (i > dota && j < dotb) {
t = a[i--] + d - '0';
if (t > 9) {
d = 1;
c[lenc++] = t % 10 + '0';
} else {
d = 0;
c[lenc++] = t + '0';
}
} else if (idotb) {
t = b[j--] + d - '0';
if (t > 9) {
d = 1;
c[lenc++] = t % 10 + '0';
} else {
d = 0;
c[lenc++] = t + '0';
}
}
}
for (; i >= 0; i--) {
t = a[i] - '0' + d;
if (t > 9) {
d = 1;
c[lenc++] = t % 10 + '0';
} else {
d = 0;
c[lenc++] = t + '0';
}
}
for (; j >= 0; j--) {
t = b[j] - '0' + d;
if (t > 9) {
d = 1;
c[lenc++] = t % 10 + '0';
} else {
d = 0;
c[lenc++] = t + '0';
}
}
if (d) {
c[lenc++] = d + '0';
}
c[lenc] = '\0';
// printf("%s\n", c);
//化简c
for (dotc = lenc - 1; dotc >= 0 && c[dotc] != '.'; dotc--);
for (i = 0; i < dotc && c[i] == '0'; i++);
if (c[i] == '.') i++;
for(j=lenc-1;j>0 && c[j]=='0' && c[j+1]!='.' &&c[j+1];j--);
for (; j >= i; j--)
printf("%c", c[j]);
printf("\n");
}
return 0;
}
题目推荐
#include
#include
#define MAX 1000
char a[MAX],b[MAX],c[MAX];
int main()
{
int i,j,k,l,m,n,la,lb,mx;
char ch;
memset(a,'0',sizeof(a));
memset(b,'0',sizeof(b));
while(~scanf("%s%s",a,b))
{
la=strlen(a);
lb=strlen(b);
a[la]='0';
b[lb]='0';
i=0;
while((a[i]-'.')&&i(lb-j)?(la-i):(lb-j);
if(i>=j)
{
for(l=mx=i+m,k=0,j=i-j;l>=0;l--)
{
if(a[l]=='.')
{
c[l]='.';
continue;
}
ch=(l-j)<0?'0':b[l-j];
c[l]=(a[l]-'0'+ch-'0'+k)%10+'0';
k=(a[l]-'0'+ch-'0'+k)/10;
}
}
else
{
for(l=mx=j+m,k=0,j=j-i;l>=0;l--)
{
if(b[l]=='.')
{
c[l]='.';
continue;
}
ch=(l-j)<0?'0':a[l-j];
c[l]=(ch-'0'+b[l]-'0'+k)%10+'0';
k=(ch-'0'+b[l]-'0'+k)/10;
}
}
if(k>0)
printf("%d",k);
while(c[mx]=='0')
mx--;
if(c[mx]=='.')
mx--;
for(i=0;i<=mx;i++)
printf("%c",c[i]);
printf("\n");
memset(a,'0',sizeof(a));
memset(b,'0',sizeof(b));
}
}
测试数据
00.000 0000.00000
0
1 9
10
998.900 001.900
1000.8
998.900 001.100
1000