【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;
}
相关推荐
miller-tsunami16 小时前
内存管理&模板
c++·算法·内存管理·模板
青少儿编程课堂16 小时前
蓝桥杯青少组·全国青少年信息素养·电子学会Scratch考级:校园智能抢答器项目解析
c++·python·算法·bfs·信息学竞赛
SZYSK17 小时前
一套人员主数据,三套事务:通行、消费、人证比对如何分事件类型
物联网·算法·harmonyos
充值内卷17 小时前
[特殊字符] 自己动手做一个类 tldraw 的桌面白板:StepDraw 开源啦(C++ + WebView2 + Canvas)
开发语言·c++
raindayinrain17 小时前
c++对象模型--内存布局,多态,运行时类型识别
开发语言·c++
怕浪猫17 小时前
不用摄像机,我把历史故事做成竖屏视频
算法·面试·github
从小白到软工17 小时前
5-2 从查表到控件:造按钮
c语言·开发语言·数据结构·经验分享·ai编程
水饺编程17 小时前
第2章:Linux 基础,解压缩【.tar.gz】压缩包
linux·c语言·汇编
郝学胜-神的一滴18 小时前
AI 编程智能体 16:从零基础搭建到精细化优化
人工智能·python·算法·语言模型·langchain·pip
cu14318 小时前
细谈IT6653的具体功能与其应用
c语言·c++·单片机·嵌入式硬件