洛谷-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
,所以需要分为位数不同和位数相同两种情况计算。