1007. 二哥领工资 (超大数求和)

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 
#include 
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<




你可能感兴趣的:(ACM)