知识铺垫(高精度算法):
在C/C++中,我们经常会碰到限定数据范围的情况,
C++规定:
int占32位,即4个字节,即int的范围是[-231,231-1],为10^9数量级
long long占64位,即8个字节,即long long的范围是[-263,263-1],为10……18数量级
如果超过该数量级,则需引入高精度算法。
1.高精度加法

A+B Problem(高精)

题目描述

高精度加法,相当于 a+b problem,不用考虑负数

输入格式

分两行输入。a,b<=10^500。

输出格式

输出只有一行,代表 $a+b$ 的值。

样例 #1

样例输入 #1

1
1

样例输出 #1

2

样例 #2

样例输入 #2

1001
9099

样例输出 #2

10100

提示

$20%$ 的测试数据,0<=a,b<=10^9;

$40%$ 的测试数据,0<=a,b<=10^18。

#include<iostream>
#include<cstring>
char s1[505],s2[505];
int a[505],b[505],c[505];
using namespace std;
int main()
{
    int la,lb,lc;// la: s1的长度, lb: s2的长度, lc: 结果的长度

    // 输入两个大数的字符串表示
    cin>>s1;
    cin>>s2;

    // 计算输入字符串的长度
    la=strlen(s1);
    lb=strlen(s2);

     // 将第一个字符串的数字转换为整数数组(反向存储)
    for(int i=0; i<la; i++)
    {
        a[la-i]=s1[i]-'0'; // s1[i] 转换为数字并存储在 a 中
    }

     // 将第二个字符串的数字转换为整数数组(反向存储)
    for(int i=0; i<lb; i++)
    {
        b[lb-i]=s2[i]-'0';// s2[i] 转换为数字并存储在 b 中
    }

    // 设置结果的最大可能长度
    lc=max(la,lb)+1;// 加一是为了处理可能的进位

    // 进行大数相加
    for(int i=1; i<=lc; i++)
    {
        c[i]+=a[i]+b[i];// 对应位相加
        c[i+1]=c[i]/10;// 计算进位
        c[i]=c[i]%10; // 当前位数值
    }

    // 去掉结果前面的零
    if(c[lc]==0&&lc>0)lc--;

    // 输出最终结果
    for(int i=lc; i>0; i--)
        cout<<c[i];// 从高位到低位输出

    return 0;

}

2.高精度减法

高精度减法

题目描述

高精度减法。

输入格式

两个整数 $a,b$(第二个可能比第一个大)。

输出格式

结果(是负数要输出负号)。

样例 #1

样例输入 #1

2
1

样例输出 #1

1

提示

  • $20%$ 数据 $a,b$ 在 long long 范围内;
  • $100%$ 数据 $0<a,b<10^10086$。
#include <iostream>
#include <cstring>
using namespace std;

// 定义字符串和数组的大小
char s1[110090], s2[10090], s3[10090];
int a[10090], b[10090], c[10090];
int flag = 0; // 用于标记结果符号

// 比较两个字符串的函数
bool compare(char s1[], char s2[]) {
    // 如果两个字符串完全相同,返回 true
    if (strcmp(s1, s2) == 0) return true;

    int u = strlen(s1), v = strlen(s2); // 获取两个字符串的长度

    // 如果 s1 长度大于 s2,返回 true(s1 更大)
    if (u > v) return true;
    // 如果 s1 长度小于 s2,返回 false(s2 更大)
    else if (u < v) return false;
    // 如果长度相等,逐字符比较
    else if (u == v) {
        for (int i = 0; i < u; i++) {
            // 返回第一个不同字符的比较结果
            if (s1[i] != s2[i]) return s1[i] > s2[i];
        }
    }
}

int main() {
    int la, lb, lc; // 字符串长度变量
    // 输入两个大数
    cin >> s1;
    cin >> s2;

    // 如果 s1 不大于 s2,则交换它们
    if (!compare(s1, s2)) {
        flag = 1; // 设置标记,表示结果是负数
        strcpy(s3, s1); // 临时保存 s1
        strcpy(s1, s2); // 将 s2 赋值给 s1
        strcpy(s2, s3); // 将原来的 s1 赋值给 s2
    }

    la = strlen(s1); // 获取 s1 的长度
    lb = strlen(s2); // 获取 s2 的长度

    // 将 s1 转换为逆序的数字数组 a
    for (int i = 0; i < la; i++) {
        a[la - i] = s1[i] - '0'; // 字符转数字,并存储在 a 中
    }

    // 将 s2 转换为逆序的数字数组 b
    for (int i = 0; i < lb; i++) {
        b[lb - i] = s2[i] - '0'; // 字符转数字,并存储在 b 中
    }

    lc = max(la, lb); // 结果的最大位数

    // 大数减法运算
    for (int i = 1; i <= lc; i++) {
        if (a[i] < b[i]) { // 如果 a 当前位小于 b 当前位
            a[i + 1]--; // 向高位借一
            a[i] += 10; // 当前位加上 10
        }
        c[i] = a[i] - b[i]; // 计算当前位的结果
    }

    // 去掉前导零
    while (c[lc] == 0 && lc > 1) lc--;

    // 如果 flag 为 1,说明结果是负数,输出负号
    if (flag == 1) cout << "-";

    // 输出结果,从最高位到最低位
    for (int i = lc; i > 0; i--) {
        cout << c[i];
    }

    return 0;
}

posted on 2024-09-26 10:14  zzzxxyy  阅读(19)  评论(0)    收藏  举报