ACM-簡單題之大明A+B——hdu1753
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行。。