跳转至

洛谷-P2142 高精度减法

题目描述

高精度减法

输入格式

两个整数a,b(第二个可能比第一个大)

输出格式

结果(是负数要输出负号)

输入输出样例

输入

2
1

输出

1

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <cmath>
#include <climits>
#include <cstdio>

using namespace std;

int n = 10100;
vector<int> num1(n), num2(n);
vector<int> res(n);

void init(vector<int> & v, string & s)
{
    int len = s.size();
    v[0] = len;
    for (int i = 1; i <= len; ++i)
        v[i] = s[len - i] - '0'; //倒序存储
}

void bigNumMinus(string & s1, string & s2)
{
    init(num1, s1);
    init(num2, s2);

    int pos = 1;
    while (pos <= num1[0] || pos <= num2[0]) {
        if (num1[pos] < num2[pos]) { //需要向高位借位
            num1[pos] += 10;
            --num1[pos + 1];
        }
        res[pos] = num1[pos] - num2[pos];
        ++pos;
    }

    //跳过前导0,判断大于1是考虑结果为0的情况
    while (res[pos] == 0 && pos > 1) --pos;

    for (int i = pos; i >= 1; --i)
        cout << res[i];
    cout << endl;
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    string s1, s2;
    cin >> s1 >> s2;
    //可能存在被减数小于减数的情况
    if (s1.size() < s2.size() || (s1.size() == s2.size() && s1 < s2)) {
        cout << "-";
        std::swap(s1, s2);
    }

    bigNumMinus(s1, s2);

    return 0;
}

这道题看上去和高精度加法类似,但是却布满坑点:

  • 两个字符串相减出现前导0,需要除去比如100-99
  • 前导0并不是所有都需要除去,比如0-0或100-100
  • 两个数相减可能为负,需要在结果前加负号,比较两个数的大小不能直接写成str1 < str2,因为比如38和370,按照字符串的比较规则是38 > 370,所以需要分为位数不同和位数相同两种情况计算。