1. 程式人生 > >ACM-簡單題之大明A+B——hdu1753

ACM-簡單題之大明A+B——hdu1753

大明A+B
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7220 Accepted Submission(s): 2533

Problem Description
話說,經過了漫長的一個多月,小明已經成長了許多,所以他改了一個名字叫“大明”。
這時他已經不是那個只會做100以內加法的那個“小明”了,現在他甚至會任意長度的正小數的加法。

現在,給你兩個正的小數A和B,你的任務是代表大明計算出A+B的值。

Input
本題目包含多組測試資料,請處理到檔案結束。
每一組測試資料在一行裡面包含兩個長度不大於400的正小數A和B。

Output
請在一行裡面輸出輸出A+B的值,請輸出最簡形式。詳細要求請見Sample Output。

Sample Input
1.1 2.9
1.1111111111 2.3444323343
1 1.1

Sample Output
4
3.4555434454

2.1

這道題。。。額,怎麼說呢,就是一悲劇啊。

題目通俗易懂,說的在明白點就是高精度加法,

長度不大於400,顯然大數問題,

這道題解法,要麼對其小數點,然後開始加吧,

要麼就是我這次做法:數分開存,加完了分別輸出,

這題說難不難,說簡單還真不簡單(廢話。。)

好吧,就是細心,各種情況都考慮考慮,

說半天廢話,我就來個解題的關鍵吧:

神奇的測試資料:

前置0,後置0,第一個是小數點,相加進位等等:

1.0000000000000                                   3 .43
34345.34                                                 32425345
8523400000                                            777.700
3435                                                        4554
0.000                                                       0.0000
99999                                                      1
1.0001                                                     2.9999
1.235262578623                                     2.29375824758243527200
23546756.345326547567454                .2142356754225653425346

00012.1                                                  1.2000

99.0000001                                            0.9999999

.0                                                            .0

答案:

1.43000000000003
32459690.34
8523400777.7
7989
0
100000
4
3.529020826205435272
23546756.5595622229900193425346
13.3
100
0

程式碼:

// 大明A+B

#include <iostream>
#include <string>
using namespace std;
string zs[3],xs[3];
int len_zs1,len_zs2,len_zs3;
int len_xs1,len_xs2,len_xs3;

void deal(string str,int k)
{
	int len,dian;
	int i;
	len=str.length();
	dian=-1;
	for(i=0;i<len;++i)
		if(str[i]=='.')
			dian=i;
	// 如果不存在小數點,即全為整數 
	if(dian==-1)
	{
		zs[k]=str;
		xs[k]="0";
	}
	// 如果沒有整數 
	else if(dian==0)
	{
		zs[k]="0";
		xs[k]=str.substr(dian+1,len);
	}
	else
	{
		zs[k]=str.substr(0,dian);
		xs[k]=str.substr(dian+1,len);
	}
	
	// 求各部分長度
	len_zs1=zs[0].length();
	len_zs2=zs[1].length();
	len_xs1=xs[0].length();
	len_xs2=xs[1].length();
}

// 求整數部分 
void find_zs()
{
	int i,j;
		
	zs[2]="";
	if(len_zs1>=len_zs2)
	{
		for(i=0;i<len_zs1-len_zs2;++i)
			zs[2]+=zs[0][i];
		for(j=0;j<len_zs2;++i,++j)
			zs[2]+=(zs[0][i]+zs[1][j]-'0');
				
		for(i=len_zs1-1;i>0;--i)
			if(zs[2][i]>'9')
			{
				zs[2][i]-=10;
				zs[2][i-1]+=1;
			}
		if(zs[2][0]>'9')
		{
			zs[2][0]-=10;
			zs[2]="1"+zs[2];
		}		
	}
	else
	{
		for(i=0;i<len_zs2-len_zs1;++i)
			zs[2]+=zs[1][i];
		for(j=0;j<len_zs1;++i,++j)
			zs[2]+=(zs[0][j]+zs[1][i]-'0');
				
		for(i=len_zs2-1;i>0;--i)
			if(zs[2][i]>'9')
			{
				zs[2][i]-=10;
				zs[2][i-1]+=1;
			}
		if(zs[2][0]>'9')
		{
			zs[2][0]-=10;
			zs[2]="1"+zs[2];
		}				
	}
		
}

// 求小數部分 
void find_xs()
{
	int i,j;

	xs[2]="";
	if(len_xs1>=len_xs2)
	{
		for(i=0,j=0;j<len_xs2;++i,++j)
			xs[2]+=(xs[0][i]+xs[1][j]-'0');
			
		for(;i<len_xs1;++i)
			xs[2]+=xs[0][i];
		
		for(i=len_xs1-1;i>0;--i)
			if(xs[2][i]>'9')
			{
				xs[2][i]-=10;
				xs[2][i-1]+=1;
			}
		
		if(xs[2][0]>'9')
		{
			xs[2][0]-=10;
			zs[0][len_zs1-1]+=1;
		}
		
	}
	else
	{
		for(i=0,j=0;i<len_xs1;++i,++j)
			xs[2]+=(xs[0][i]+xs[1][j]-'0');
			
		for(;j<len_xs2;++j)
			xs[2]+=xs[1][j];
		
		for(i=len_xs2-1;i>0;--i)
			if(xs[2][i]>'9')
			{
				xs[2][i]-=10;
				xs[2][i-1]+=1;
			}
		
		if(xs[2][0]>'9')
		{
			xs[2][0]-=10;
			zs[0][len_zs1-1]+=1;
		}
	}
	
}

// 判斷小數是否為0 
bool judge_xs(void)
{
	int i;
	for(i=0;i<len_xs3;++i)
		if(xs[2][i]!='0')
			return 0;
	return 1;
}

void xiuzheng(void)
{
	
	// 小數尾部0去除
	int i;
	for(i=len_xs3-1;i>=0;--i)
		if(xs[2][i]!='0')
			break;
	if(i!=len_xs3-1)	
		xs[2]=xs[2].substr(0,i+1);	
	// 小數位數長度若改變,要更新 
	len_xs3=xs[2].length();
	
	// 整數頭部0去除
	for(i=0;i<len_zs3;++i)
		if(zs[2][i]!='0' || i==len_zs3-1)
			break;
	if(i!=0)
		zs[2]=zs[2].substr(i,len_zs3-1);
	len_zs3=zs[2].length();
}

int main()
{
	string str1,str2;
	bool iszero;
	while(cin>>str1>>str2)
	{
		deal(str1,0);
		deal(str2,1);
		
		// 先求小數部分,再求整數部分,小數會有進位 
		find_xs();
		find_zs();
		len_zs3=zs[2].length();
		len_xs3=xs[2].length();
		xiuzheng();
		
		iszero=judge_xs();
		if(iszero)	cout<<zs[2]<<endl;
		else	cout<<zs[2]<<"."<<xs[2]<<endl;		
	}
	
	return 0;
} 

PS:這道題,用JAVA做,不到20行。。