原題
分類
雜題·大位整數運算
題意
計算從任意兩個長度在1000以內的正整數的和。
輸入/輸出 | 要求與格式 |
---|---|
輸入內容 | 最開始一行開始輸入樣例數,對每個樣例一行輸入兩個正整數(空格分開) |
輸出結果 | 結果爲兩數和 |
輸出格式 | 每個案例結果第一行爲"Case X:",第二行爲計算結果,兩個案例結果間一個空行 |
題解
這道題說明了整數長度在1000以內,因此,一般的long long這種系統的整數類型是不夠的,我們必須得用字符串來操作。
計算的方法其實很簡單,就是我們小學算加法的時候用到的【豎式計算】。
雖然方法簡單,但是我們還是需要自己多舉幾個例子,從其中找到普遍的規律,再來編程。
多舉幾個例子,稍微總結一下,可以大概總結爲以下三種
- 無進位,結果位數與加數的最大位數相同
- 有進位,結果位數與加數的最大位數相同
- 有進位,結果位數比加數的最大位數多1
如下圖所示
那麼,我們需要考慮的也可以總結爲以下兩點:
- 運算過程中的進位
- 最終結果的位數
首先,我們構思一下輸入,我選擇的是string字符串(怎麼說畢竟是系統庫,有API呀)。
然後就是我們之前考慮的兩個問題了。
第一個問題——計算進位。運算的時候,我們會先對齊兩個加數相應的位(個位、十位、……)。對齊後,從最後一位(個位)開始對應數字相加得到一個數tmp,再將tmp/10的結果加到十位的計算中,然後最終結果的個位即爲tmp%10。以後的每一位都是類似的算法,循環解決問題,對於最高位只要稍微處理一下就可以了。
第二個問題——結果位數。這個很好辦,我們在計算前就先定義好一個string res
用來存放結果,這個res就是兩個數中最長的再往前放一個前導0,這就涉及【字符串拼接】。當計算完最後結果時,如果最大爲爲0,說明計算時最高位沒有進位,我們可以就要把多餘的前導0抹去,這就涉及【字符串截取】
(例如:12 + 999,我們就可以先暫定string res = "0999"
,有人也許會覺得應該設置爲string res = "0000"
,但是實際上沒有必要,因爲每一位計算的結果都會不斷刷新res,res的初始值根本不重要,只有其最大可能位數是最重要的)
操作 | 示例代碼 | 解釋 |
---|---|---|
字符串拼接 | string a = "0", b = "1", c = a + b; |
將a在前b在後拼接成一個新字符串c |
截取子串 | string res = c.substr(1); |
將字符串c從下標1開始(包括)截取到末尾生成一個型字符串res |
題解代碼
HDU(C++/G++)AC代碼如下:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T;
string a, b;
string at, bt;
int cnt = 1;
//接收樣例數
cin >> T;
while (T--)
{
//接收數據
cin >> a >> b;
at = a;
bt = b;
//長度處理——長的在上
if (a.length() < b.length())
swap(a, b);
//數據準備
int len_min = b.length();
int len_max = a.length();
string res = "0";
res += a;
int add_once;
int add_next = 0;
//開始計算
while (max(len_min, len_max) >= 0)
{
--len_min;
--len_max;
if (len_min > -1)
add_once = a[len_max] + b[len_min] - 96 + add_next;
else
{
if (len_max > -1)
add_once = a[len_max] - 48 + add_next;
else
add_once = add_next;
}
add_next = add_once / 10;
res[len_max + 1] = add_once % 10 + 48;
}
//去除前導0
if (res[0] == '0')
res = res.substr(1);
//打印結果
cout << "Case " << cnt << ':' << endl;
cout << at << " + " << bt << " = " << res << endl;
if (T)
cout << endl;
++cnt;
}
return 0;
}
評價
這道題應該算是一道模板題,大位整數的四則運算,應對這種題,最好還是寫成一套靠譜的模板好一些。
補充
這道題在C++裏雖然·是道模板題,但是在Java裏卻可以說和HDU.1000 A + B Problem幾乎是一個難度級別的,因爲Java中系統裏的包就有BigInteger大數類,很容易操作,有興趣的話可以去稍微瞭解一下。
後話
寫這題的題解的時候,雖然覺得寫得勉強還算詳細,但是總覺得不太對勁,可能是有些段落文字太多,顯得亂七八糟😅😅😅,亦或是因爲有些小的細枝末節的地方沒有詳細講解如何處理(比如較短的字符串如何處理、兩個結果間一個空行格式如何控制)其實代碼裏都有,但是我覺得都拋出來放到題解裏會更亂,所以就沒加。有好的建議評論區提提,謝謝。