题解
部分数字的减法
1 条题解
-
0
解题思路
题目要我们先从两个大整数里截取第 l 位到第 r 位,再计算这两段的差。因为位数最多有 100 位,直接按整数存会溢出,所以还是用高精度减法。
整体分四步:
- 截取:用字符串下标直接取出第 l~r 位,得到两段数字。
- 比大小:两段位数相同,从高位往低位比较,判断结果的正负。
- 相减:把数字倒着存进数组(个位在最前),逐位相减,不够减就向高一位借 1。
- 去前导 0:如果差的前面是 0(比如
12345-12300得到45),输出时要跳过这些 0。
如果第一个数截出来的比第二个小,结果就是负数,先输出负号,再用较大的减较小的。
参考代码
#include <iostream> using namespace std; char s1[105], s2[105]; // 两个大整数(用字符串读入) int a[105], b[105]; // 截取出来的两段数字,个位放在下标0 int ans[105]; // 减法结果 int main() { int l, r; cin >> s1; // 第一个大整数 cin >> s2; // 第二个大整数 cin >> l >> r; // 截取第l位到第r位 int len = r - l + 1; // 截取出来的长度 // 取出两个大整数的第l到r位 char t1[105], t2[105]; for (int i = 0; i < len; i++) { t1[i] = s1[l - 1 + i]; t2[i] = s2[l - 1 + i]; } t1[len] = 0; t2[len] = 0; // 比较两段数字谁更大(0相同,1第一个大,-1第二个大) int cmp = 0; for (int i = 0; i < len; i++) { if (t1[i] != t2[i]) { cmp = (t1[i] > t2[i]) ? 1 : -1; break; } } // 把数字倒着存进数组,个位放最前面,方便借位 for (int i = 0; i < len; i++) { a[i] = t1[len - 1 - i] - '0'; b[i] = t2[len - 1 - i] - '0'; } // 如果第二个数更大,结果是负数:先输出负号,再反过来大减小 if (cmp < 0) { cout << "-"; for (int i = 0; i < len; i++) { int t = a[i]; a[i] = b[i]; b[i] = t; } } // 逐位相减,不够减就向高一位借1 for (int i = 0; i < len; i++) { ans[i] += a[i] - b[i]; if (ans[i] < 0) { ans[i] += 10; ans[i + 1] -= 1; } } // 去掉结果开头的0(比如12345-12300得到的45,前面的0不要) int pos = len - 1; while (pos > 0 && ans[pos] == 0) pos--; // 从高位到低位输出 for (int i = pos; i >= 0; i--) { cout << ans[i]; } return 0; }复杂度分析
截取出的两段长度为 len,只需要扫一遍,时间复杂度是 O(len);几个长度相等的数组,额外空间复杂度也是 O(len)。
- 1