- 第 154 篇 -
Date: 2025 - 11- 21
Author: 郑龙浩(仟墨)
经典高精度 5道题 加减乘除
文章目录
- [经典高精度 5道题 加减乘除](#经典高精度 5道题 加减乘除)
-
- [1_洛谷P1601_A+BProblem 高精度 + 高精度](#1_洛谷P1601_A+BProblem 高精度 + 高精度)
- [2_洛谷P2142_高精度减法 高精度 - 高精度](#2_洛谷P2142_高精度减法 高精度 - 高精度)
- [3_P1303_高精度×高精度Problem 高精度 * 高精度](#3_P1303_高精度×高精度Problem 高精度 * 高精度)
- [4_洛谷P1591阶乘数码_高精x低精 高精度 * 低精度](#4_洛谷P1591阶乘数码_高精x低精 高精度 * 低精度)
- [5_洛谷P1480ABProblem 高精度 / 低精度](#5_洛谷P1480ABProblem 高精度 / 低精度)
1_洛谷P1601_A+BProblem 高精度 + 高精度
cpp
// 6_高精度算法\高精度_第3遍刷题_2025-11-21\1_洛谷P1601_A+BProblem_高精.cpp
// Author: 郑龙浩(仟墨)
// Date: 2025-11-21
// 第3次刷题,用时:
#include "iostream"
using namespace std;
typedef long long ll;
const ll N = 500 + 5;
ll len1 = 0, len2 = 0, len = 0;
void StrToInt(string &S, ll nums1[], ll &len) {
int S_len = S.size();
for (int i = S_len - 1; i >= 0; i--) {
nums1[len++] = S[i] - '0';
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
string S1, S2;
cin >> S1 >> S2;
ll nums1[N] = {0}, nums2[N] = {0};
StrToInt(S1, nums1, len1);
StrToInt(S2, nums2, len2);
ll ans[N] = {0};
len = max(len1, len2);
// 模拟竖式
for (int i = 0; i < len; i++) {
ans[i] += nums1[i] + nums2[i];
ans[i + 1] = ans[i] / 10;
ans[i] %= 10;
}
if (ans[len] > 0) len++; // 进位溢出判断
for (int i = len - 1; i >= 0; i--) {
cout << ans[i];
}
return 0;
}
2_洛谷P2142_高精度减法 高精度 - 高精度
cpp
// 6_高精度算法\高精度_第3遍刷题_2025-11-21\2_洛谷P2142_高精度减法.cpp
// Author: 郑龙浩(仟墨)
// Date: 2025-11-21
// 第3次刷题,用时:48min
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll N = 10086 + 5;
ll len1, len2, len;
string sign = ""; // 符号
void StrToll(string &S, ll nums[], ll &len) {
ll Slen = S.size();
for (ll i = Slen - 1; i >= 0; i--) {
nums[len++] = S[i] - '0';
}
}
// 比较两个数字大小(用string比较更加高效,所以尽量不要使用nums数组进行比较)
// >= 返回1,< 返回0
ll cmp(string &S1, string &S2) {
if (len1 > len2) return 1;
else if (len1 < len2) return 0;
else return S1 >= S2;
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
ll nums1[N] = {0}, nums2[N] = {0}, ans[N] = {0};
string S1, S2;
cin >> S1 >> S2;
StrToll(S1, nums1, len1);
StrToll(S2, nums2, len2);
len = max(len1, len2);
// 让大数 - 小数
if (cmp(S1, S2)) {
for (ll i = 0; i < len; i++) {
ans[i] += nums1[i] - nums2[i];
// 如果是负数,必须借位
if (ans[i] < 0) {
ans[i + 1] -= 1;
ans[i] += 10;
}
}
} else {
sign.push_back('-'); // 负数
for (ll i = 0; i < len; i++) {
ans[i] += nums2[i] - nums1[i];
// 如果是负数,必须借位
if (ans[i] < 0) {
ans[i + 1] -= 1;
ans[i] += 10;
}
}
}
// 去除前导0
while (len > 1 && ans[len - 1] == 0) len--;
cout << sign; // 打印符号
for (ll i = len - 1; i >= 0; i--) cout << ans[i];
return 0;
}
3_P1303_高精度×高精度Problem 高精度 * 高精度
cpp
// 3_P1303_高精度×高精度Problem.cpp
// Author: 郑龙浩(仟墨)
// Date: 2025-11-21
// 第3次刷题,用时:48min
#include "bits/stdc++.h"
using namespace std;
const int N = 2000 + 5;
int len1 = 0, len2 = 0, len = 0;
int nums1[N] = {0}, nums2[N] = {0}, ans[2 * N] = {0};
void StrToInt(string &s, int nums[], int &len) {
int sl = s.size();
for (int i = sl-1; i >= 0; i--) {
nums[len++] = s[i] - '0';
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
string s1, s2;
cin >> s1 >> s2;
// 特判:
if (s1 == "0" || s2 == "0") {
cout << 0;
return 0;
}
StrToInt(s1, nums1, len1);
StrToInt(s2, nums2, len2);
len = len1 + len2;
for (int i = 0; i < len2; i++) {
int cur = nums2[i];
for (int j = 0; j < len1; j++) {
ans[i + j] += cur * nums1[j];
ans[i + j + 1] += ans[i + j] / 10;
ans[i + j] %= 10;
}
}
// 处理前导0
while (len > 1 && ans[len - 1] == 0) len--;
for (int i = len - 1; i >= 0; i--) {
cout << ans[i];
}
return 0;
}
4_洛谷P1591阶乘数码_高精x低精 高精度 * 低精度
cpp
// 6_高精度算法\高精度_第3遍刷题_2025-11-21\4_洛谷P1591阶乘数码_高精x低精.cpp
// Author: 郑龙浩(仟墨)
// Date: 2025-11-21
// 第3次刷题,用时:41min
#include "bits/stdc++.h"
using namespace std;
const int N = 2000005;
int len = 1; // 因为默认为1,所以有一位
int nums[N] = {1}; // 默认1
void div(int nums[], int &num) {
int carry = 0; // 存储余数
for (int i = 0; i < len; i++) {
nums[i] = nums[i] * num + carry;
carry = nums[i] / 10;
nums[i] %= 10;
}
while (carry > 0) {
nums[len] = carry % 10;
carry /= 10;
len++;
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int t, n, a; cin >> t;
for (int i = 0; i < t; i++) {
// 每次都要记得清零
nums[0] = 1;
len = 1;
cin >> n >> a;
int ans[N] = {0};
for (int j = 2; j <= n; j++) {
div(nums, j);
}
int cnt = 0;
for (int j = 0; j < len; j++) {
if (nums[j] == a) {
cnt++;
}
}
cout << cnt << '\n';
}
return 0;
}
5_洛谷P1480ABProblem 高精度 / 低精度
cpp
// 6_高精度算法\高精度_第3遍刷题_2025-11-21\5_洛谷P1480ABProblem.cpp
// Author: 郑龙浩(仟墨)
// Date: 2025-11-21
// 第3次刷题,用时:54min
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll N = 2000005;
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
string s;
ll n;
cin >> s >> n;
ll len = s.size();
// 为0
if (len == 1 && s[0] == '0') {
cout << 0;
return 0;
}
// 高精除法 - 正序计算即可
ll ans[N] = {0}, num;
ll carry = 0;
for (ll i = 0; i < len; i++) {
num = s[i] - '0';
carry = carry * 10 + num; // 上一步的余数 * 10 + 当前位 --> 组合数
ans[i] = carry / n;
carry %= n;
}
// 去除前导0
ll start = 0; // 数字的开头位
while (start < len - 1 && ans[start] == 0) {
start++;
}
for (ll i = start; i < len; i++) {
cout << ans[i];
}
return 0;
}