1007. 二哥領工資 (超大數求和)
阿新 • • 發佈:2019-01-11
題目描述
二哥當了多年的助教,今天終於要發工資了!二哥正在高興之際,得知工資是分兩部分發放的。第一部分是這學期的工資,另一部分是之前所有學期的工資總和。而領取工資時,出納員會問二哥,兩部分工資加在一起是多少,如果二哥回答錯了,就只能領到這個學期的工資之前所有學期的勞動就白費了。
二哥從小道訊息得知,出納員是個對數字敏感的人,不能有一點差錯,所以二哥需要一個程式來幫他算出精確的工資總和。
輸入格式
輸入共兩行,每行是一個十進位制表示的工資金額(沒有正負號,小數點後有兩位數字)。
輸出格式
輸出共一行,即精確的工資總和(沒有正負號,小數點後有兩位數字)。
說明
工資金額的有效數字位數不超過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; }