题目描述
二哥当了多年的助教,今天终于要发工资了!二哥正在高兴之际,得知工资是分两部分发放的。第一部分是这学期的工资,另一部分是之前所有学期的工资总和。而领取工资时,出纳员会问二哥,两部分工资加在一起是多少,如果二哥回答错了,就只能领到这个学期的工资之前所有学期的劳动就白费了。
二哥从小道消息得知,出纳员是个对数字敏感的人,不能有一点差错,所以二哥需要一个程序来帮他算出精确的工资总和。
输入格式
输入共两行,每行是一个十进制表示的工资金额(没有正负号,小数点后有两位数字)。
输出格式
输出共一行,即精确的工资总和(没有正负号,小数点后有两位数字)。
说明
工资金额的有效数字位数不超过200位,并保证有小数点。
Sample Input
123.45
543.21
Sample Output
666.66
题目分析
这个题的本质就是大数求和,因为题中指出,数字的长度不超过200位,显然题目想说的是二哥的工资可能是一笔巨款,没有任何一种计算机数据类型可以存储这么大的数字。
解决的办法就是模拟手工加法,从低位到高位,依次相加,并保存进位。
输入可以用string类来存储为字符串,计算时将其转化为一个整形数组,倒序保存,对两个数组进行相加,最后对和数组倒序输出即可。另外需要注意到的是,题目中说数据必然带2位小数,也只会带二位小数,因此还需要注意对小数点的处理,包括存储为整形数组时的跳过小数点和输出时在相应的位置加上小数点。
C++实现
#include<iostream>
#include<string>
#define maxSize 205
using namespace std;
int main() {
string cnum1;
string cnum2;
cin >> cnum1 >> cnum2;
int num1[maxSize] = { 0 };
int num2[maxSize] = { 0 };
int sum[maxSize] = { 0 };
for (int i = cnum1.size()-1,k=0; i >= 0; i--) {
if (i != cnum1.size() - 3) {
num1[k] = cnum1[i] - '0';
// cout << num1[k];
k++;
}
}
//cout << endl;
for (int i = cnum2.size()-1,k=0; i>=0; i--)
{
if (i != cnum2.size() - 3) {
num2[k] = cnum2[i] - '0';
// cout << num2[k];
k++;
}
}
// cout << endl;
int carry=0,tmp = 0;
for (int i = 0;; i++) {
tmp = num1[i] + num2[i] + carry;
sum[i] = tmp % 10;
carry = tmp / 10;
// cout << sum[i];
if (i>cnum1.size()-1&&i>cnum2.size()-1) {
break;
}
}
// cout << endl;
int i;
for ( i = maxSize-1;; i--) {
if (sum[i] != 0)
break;
}
for (i; i >= 0; i--) {
if (i == 2) {
cout << sum[i];
cout << ".";
}
else
cout << sum[i];
}
cout << endl;
return 0;
}
Judging... PROB=1007 LANG=C++ Accepted (Time: 0ms, Memory: 1084kb) Accepted (Time: 0ms, Memory: 1076kb) Accepted (Time: 0ms, Memory: 1076kb) Accepted (Time: 0ms, Memory: 1084kb) Accepted (Time: 0ms, Memory: 1076kb) Accepted (Time: 0ms, Memory: 1088kb) Accepted (Time: 0ms, Memory: 1088kb) Accepted (Time: 0ms, Memory: 1088kb) Accepted (Time: 0ms, Memory: 1076kb) Accepted (Time: 0ms, Memory: 1084kb)