http://acm.sjtu.edu.cn/OnlineJudge/problem/1007
题目描述
二哥当了多年的助教,今天终于要发工资了!二哥正在高兴之际,得知工资是分两部分发放的。第一部分是这学期的工资,另一部分是之前所有学期的工资总和。而领取工资时,出纳员会问二哥,两部分工资加在一起是多少,如果二哥回答错了,就只能领到这个学期的工资之前所有学期的劳动就白费了。
二哥从小道消息得知,出纳员是个对数字敏感的人,不能有一点差错,所以二哥需要一个程序来帮他算出精确的工资总和。
输入格式
输入共两行,每行是一个十进制表示的工资金额(没有正负号,小数点后有两位数字)。
输出格式
输出共一行,即精确的工资总和(没有正负号,小数点后有两位数字)。
说明
工资金额的有效数字位数不超过200位,并保证有小数点。
Sample Input
123.45
543.21
Sample Output
666.66
***********************************************************************************************************************************
分析
这个题的说明中,有效数字位数不超过200位,所以数值是一个超大的数,对目前普通电脑的内存有限,表达不了这么大的数字。
虽然用float,double型做不到,我们可以把它转化为字符串的形式,再按照普通的一位数加法来计算,设置一个进位,如果两个一位数相加大于10,则进位为1,否则为0;
如何把在字符与数值之间转换呢?
把 数字9转化字符‘9’, 只要 9+‘0’就可以了 ,即 ‘9’(字符) = 9(数字)+ ‘0’(字符)。
把字符‘9’转化为数字9,则用 ‘9’-‘0’, 即 9(数字)=‘9’(字符)-‘0’(字符)。
为什么能这样做呢,因为在ASCII码表中, 字符‘0’对应48, 字符‘9’对应57, 所以我们有
‘9’(字符) = 9(数字)+ ‘0’(字符)
48 = 9 + 48
代码:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string before; //往年的工资总和
string thisOne; //今年的工贸
string sum; //总工资
char temp; //临时变量
char carray = 0; //进位
int lenBe = 0;
int lenTh = 0;
cin>>before;
cin>>thisOne;
lenBe = before.size();
lenTh = thisOne.size();
//倒序 如把 123.45 变换成 54.321
//为了方便从个位开始进位计算
for(int i = 0; i < lenBe/2; i++)
{
temp = before[i];
before[i] = before[lenBe-i-1];
before[lenBe-i-1] = temp;
}
for(int i = 0 ; i < lenTh/2; i++)
{
temp = thisOne[i];
thisOne[i] = thisOne[lenTh-i-1];
thisOne[lenTh-i-1] = temp;
}
carray = 0; //初始进位为0
for(int i = 0; i < 2; i++)
{
char a = before[i] - '0';
char b = thisOne[i] - '0';
char c = a + b + carray;
if(c>=10)
{
carray = 1;
sum.push_back(c%10+'0');
}
else
{
sum.push_back(c+'0');
carray = 0;
}
}
sum.push_back('.'); //第三位为小数点,不参与运算
if(lenBe>=lenTh) //比较哪个数值的长度, 以前工资总和长度大
{
for(int i = 3; i < lenTh; i++) //i = 3, 从倒序字符串的小数点后第一位开始
{
char a = before[i] - '0'; //减 '0', 把字符型数据转成数字型数据
char b = thisOne[i] - '0';
char c = a + b + carray;
if(c>=10) //相加和大于等于10,进位
{
carray = 1;
sum.push_back(c%10+'0'); //加'0', 把数字型数据转成字符型数据
}
else
{
sum.push_back(c+'0');
carray = 0;
}
}
for(int i = lenTh; i < lenBe; i++)
{
char b = before[i] - '0';
char c = b + carray;
if(c>=10)
{
carray = 1;
sum.push_back(c%10+'0');
}
else
{
sum.push_back(c+'0');
carray = 0;
}
}
if(1==carray) //最高位进1,则为1
{
sum.push_back('1');
}
}
else //这个学期工资总和长度大
{
for(int i = 3; i < lenBe; i++)
{
char a = before[i] - '0';
char b = thisOne[i] - '0';
char c = a + b + carray;
if(c>=10)
{
carray = 1;
sum.push_back(c%10+'0');
}
else
{
sum.push_back(c+'0');
carray = 0;
}
}
for(int i = lenBe; i < lenTh; i++)
{
char b = before[i] - '0';
char c = b + carray;
if(c>=10)
{
carray = 1;
sum.push_back(c%10+'0');
}
else
{
sum.push_back(c+'0');
carray = 0;
}
}
if(1==carray)
{
sum.push_back('1');
}
}
//倒序
int lenSum = sum.size();
for(int i = 0; i < lenSum/2; i++)
{
temp = sum[i];
sum[i] = sum[lenSum-i-1];
sum[lenSum-i-1] = temp;
}
cout<<sum;
return 0;
}