Skip to content

Latest commit

 

History

History
61 lines (47 loc) · 2.78 KB

1074. 宇宙无敌加法器.md

File metadata and controls

61 lines (47 loc) · 2.78 KB

【PAT B-1074】宇宙无敌加法器

题意概述

在 PAT 星人开挂的世界里,每个数字的每一位都是不同进制的,这种神奇的数字称为PAT数。每个 PAT 星人都必须熟记各位数字的进制表,例如……0527就表示最低位是 7 进制数、第 2 位是 2 进制数、第 3 位是 5 进制数、第 4 位是 10 进制数等等。每一位的进制 d 或者是 0(表示十进制)、或者是[2, 9]区间内的整数。

在这样的数字系统中,即使是简单的加法运算也变得不简单。例如对应进制表0527,该如何计算6203 + 415呢?我们得首先计算最低位:3 + 5 = 8;因为最低位是 7 进制的,所以我们得到 1 和 1 个进位。第 2 位是:0 + 1 + 1(进位)= 2;因为此位是 2 进制的,所以我们得到 0 和 1 个进位。第 3 位是:2 + 4 + 1(进位)= 7;因为此位是 5 进制的,所以我们得到 2 和 1 个进位。第 4 位是:6 + 1(进位)= 7;因为此位是 10 进制的,所以我们就得到 7。最后我们得到:6203 + 415 = 7201。

输入输出格式

输入首先在第一行给出一个 N 位的进制表,以回车结束。随后两行,每行给出一个不超过 N 位的非负的 PAT 数。

在一行中输出两个 PAT 数之和。

数据规模

$$0<N\le 20$$

算法设计

输入的数最多有 20 位,即使用 long long 也存储不下,需要用字符串存储。为了方便加和,可以将输入的 3 个字符串都翻转过来。然后对高精度整数求和程序进行略微修改即可。

注意点

  1. 对于输入的两个要加和的字符串都是 0,输出应为 0。
  2. 如果加和结果不是 0,不要输出前导 0,例如 0723,只应输出 723。
  3. 注意加和最后结果仍有进位的情况,例如 999+111 最后结果仍有一个进位,最后结果应该是 4 位的字符串。

C++代码

#include <bits/stdc++.h>
using namespace std;
using gg = long long;
//默认输入的a和b均为非负整数,n为进制
string Plus(string a, string b, string n) {
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());
    reverse(n.begin(), n.end());
    string ans;
    gg carry = 0;  //进位
    for (gg i = 0; i < a.size() or i < b.size() or carry != 0; ++i) {
        gg p1 = i < a.size() ? a[i] - '0' : 0,
           p2 = i < b.size() ? b[i] - '0' : 0;
        gg k = p1 + p2 + carry, t = n[i] == '0' ? 10 : n[i] - '0';
        ans.push_back(k % t + '0');
        carry = k / t;
    }
    ans.erase(ans.find_last_not_of('0') + 1, ans.size());
    reverse(ans.begin(), ans.end());  //要进行翻转
    return ans.empty() ? "0" : ans;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    string a, b, n;
    cin >> n >> a >> b;
    cout << Plus(a, b, n);
    return 0;
}