【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;
}
相关推荐
熊文豪6 分钟前
探索CANN ops-nn:高性能哈希算子技术解读
算法·哈希算法·cann
熊猫_豆豆23 分钟前
YOLOP车道检测
人工智能·python·算法
艾莉丝努力练剑38 分钟前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
Once_day1 小时前
C++之《程序员自我修养》读书总结(1)
c语言·开发语言·c++·程序员自我修养
Trouvaille ~1 小时前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
偷吃的耗子1 小时前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn
坚果派·白晓明1 小时前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
小镇敲码人1 小时前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
dazzle2 小时前
机器学习算法原理与实践-入门(三):使用数学方法实现KNN
人工智能·算法·机器学习