题解
守护者的问题
1 条题解
-
0
解题思路
两个大整数的位数在 10 到 500 之间,不能用普通的 int 或 long long,要用高精度减法。
思路还是像列竖式一样,从个位开始一位一位减:
- 把两个数当字符串读进来。
- 先比较谁大:位数多的数大;位数一样,就从最高位往低位一位一位比。
- 用大的数减小的数:把大数放前面,逐位相减,哪一位不够减就向高一位借 1(那一位加 10)。
- 如果答案是负数(小的减大的),输出的时候要加负号。
- 最后从高位往低位输出,去掉前导 0。
参考代码
// 用途:两个超级大的整数(10~500位)相减,输出差 // 大整数用字符数组读入,倒序存入数组逐位相减(高精度减法) #include <iostream> using namespace std; int main() { char n[505], m[505]; int a[505] = {0}, b[505] = {0}, r[505] = {0}; cin >> n >> m; int ln = 0, lm = 0; while (n[ln]) ln++; // n的位数 while (m[lm]) lm++; // m的位数 // 比较n和m谁大(先比位数,再比高位) int neg = 0; if (ln < lm) neg = 1; else if (ln == lm) { for (int i = 0; i < ln; i++) { if (n[i] < m[i]) { neg = 1; break; } if (n[i] > m[i]) break; } } char *big = neg ? m : n, *small = neg ? n : m; // 大的放前面 int lbig = neg ? lm : ln, lsmall = neg ? ln : lm; for (int i = 0; i < lbig; i++) a[i] = big[lbig - 1 - i] - '0'; // 倒序 for (int i = 0; i < lsmall; i++) b[i] = small[lsmall - 1 - i] - '0'; for (int i = 0; i < lbig; i++) { // 逐位相减 r[i] = a[i] - b[i]; if (r[i] < 0) { r[i] += 10; a[i + 1]--; } // 不够减就借位 } if (neg) cout << '-'; // 结果为负数时加负号 int len = lbig; while (len > 1 && r[len - 1] == 0) len--; // 去掉前导0 for (int i = len - 1; i >= 0; i--) cout << r[i]; return 0; }复杂度分析
减法要处理所有位,n 最多 500 位,时间复杂度是 O(n),空间复杂度也是 O(n),1 秒内轻松完成。
- 1