【C/C++】经典高精度算法 5道题 加减乘除「复习」

- 第 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;
}
相关推荐
顾安r1 小时前
11.21 脚本 网页优化
linux·前端·javascript·算法·html
kk”2 小时前
C++ map
开发语言·c++
车端域控测试工程师2 小时前
Autosar网络管理测试用例 - TC003
c语言·开发语言·学习·汽车·测试用例·capl·canoe
共享家95272 小时前
特殊类的设计
开发语言·c++
WolfGang0073212 小时前
代码随想录算法训练营Day27 | 56.合并区间、738.单调递增的数字、968.监控二叉树
算法
信奥卷王2 小时前
2025年9月GESPC++三级真题解析(含视频)
开发语言·c++·算法
努力学习的小廉2 小时前
我爱学算法之—— BFS之FLoodFill算法
算法·宽度优先
天选之女wow3 小时前
【Hard——Day8】65.有效数字、68.文本左右对齐、76.最小覆盖子串
linux·运维·redis·算法·leetcode
EXtreme353 小时前
征服 C 语言文件 I/O:透视数据流、FILE* 核心机制与高效实践全指南
c语言··文件io