以下纯属是自己学习csp过程中的一些记录,方便自己后续复盘,随心写,不必当真。

题目791:高精度加法

算法思想:


        什么是高精度?         A.length<<10e6 ,a<<10e9 

然后在这个情况下进行加减乘除如 A+B、A-B、A*b、A/b等的组合就是高精度运算。

我们普通的加法手算如下

例如计算:567 + 28

先个位相加: 7 + 8 = 15,所以结果的个位是5,向十位进 1

再十位相加: 6 + 2 + 1(进位)= 9, 所以十位是 9,向百位进 0

再百位相加: 5 + 0 = 5, 所以结果的百位是 5

综上,计算结果为 595

算法计算思路:

计算 567 + 28

用 a, b 两个字符串存储输入。a = 567, b = 28

为了方便计算,(因为加法要从各位开始,倒序存放符合计算规律)将两个数分别 倒序 存放在 A, B 两个整数数组中。 A = [7, 6, 5], B = [8, 2]

新建整数数组 res保存结果,整型变量 c保存进位,初始 c= 0.

将各个位上的数字相加,求出结果对应位上的数字和进位。

例如对个位计算: A[0] + B[0] = 7 + 8 = 15, 结果个位上是 5,进位是 1. 所以 res[0] = 5, 进位 c = 1

最后把结果数组 res 中就保存了计算倒序结果,倒序输出就是答案。

代码实现:O(n+m)

// 高精度加法
#include 
#include 
using namespace std;
vector add(vector &a, vector &b)
{
    // c为进位
    int c = 0;
    vector res;
    // 如果数组a和b有没遍历完的,进行循环
    for (int i = 0; i < a.size() || i < b.size(); i++)
    {
        // 没遍历完的,加到进位中 此时c=a[i]+b[i]+c
        if (i < a.size())
            c += a[i];
        if (i < b.size())
            c += b[i];
        // 结果只需要保存c对10的模
        res.push_back(c % 10);
        // c变为c/10 进位为1下次循环加
        c /= 10;
    }
    // 如果数组全部遍历完,还需要考虑最高位是否有进位,若有则最高位+1
    if (c)
        res.push_back(1);
    return res;
}
int main()
{
    string n, m;
    cin >> n >> m;
    vector a, b;
    // a,b都为字符串,可以遍历,将每个字符转为int 存入数组 为后续加法做准备
    for (int i = n.size() - 1; i >= 0; i--)
        a.push_back(n[i] - '0');
    for (int i = m.size() - 1; i >= 0; i--)
        b.push_back(m[i] - '0');
    auto c = add(a, b);
    // 输出结果
    for (int i = c.size() - 1; i >= 0; i--)
        cout << c[i];
    return 0;
}

题目792:高精度减法

算法思想:

和高精度+法差不多,值得注意的是:
1、减法的借位处理,不管借不借位,都可以把(t+10)%10加进数组!
2、相减为负数的处理:先进行判断大小,保证减法都是大减小,最后考虑符号问题。
3、前导0的处理

代码实现:O(n)

#include 
#include 
#include 
using namespace std;
// 判断a>=b
bool cmp(vector &a, vector &b)
{
    // a,b长度不一,长的大
    if (a.size() != b.size())
        return a.size() > b.size();
    // 长度相等 逐位比较 最高位在最后面所以反着比
    for (int i = a.size() - 1; i >= 0; i--)
        if (a[i] != b[i]) return a[i] > b[i];
    // 相等返回true
    return true;
}
vector sub(vector &a, vector &b)
{
    vector res;
    int t = 0;
    // 减法从个位开始
    for (int i = 0; i < a.size(); i++)
    {
        // t=0则 t=a[i]  t=1则t=a[i]-1
        t = a[i] - t;
        // 如果被减数还有位数
        if (i < b.size())
            // t减去被减数
            t -= b[i];
        // t<0则t=10+t 借位  t>=0则t=t 不借位
        res.push_back((t + 10) % 10);
        // 借位则t=1 否则t=0
        if (t < 0) t = 1;
        else t = 0;
    }
        // 去除多余的0   003=3
        while (res.size() > 1 && res.back() == 0) res.pop_back();
        return res;
}
    int main()
    {
        string n, m;
        cin >> n >> m;
        vector a, b;
        //反向读取字符串
        for (int i = n.size() - 1; i >= 0; i--)
            a.push_back(n[i] - '0');
        for (int i = m.size() - 1; i >= 0; i--)
            b.push_back(m[i] - '0');
        // 调用函数比大小
        if (cmp(a, b))
        {
            auto c = sub(a, b);
            for (int i = c.size() - 1; i >= 0; i--)
                cout << c[i];
        }
        else
        {
            auto c = sub(b, a);
            //带上-号
            cout<<"-";
            for (int i = c.size() - 1; i >= 0; i--)
                cout << c[i];
        }
        return 0;
    }

题目793:高精度乘法

算法思想:

和高精度+-法差不多,值得注意的是:
1、乘法的进位处理
2、特殊判断,如果×0的话,直接输出结果
3、注意最高位,最后一次乘完要判断t的大小,为1说明最高位有进位,手动添加进数组即可。

代码实现:O(n)

#include
#include
#include
using namespace std;
//高精度乘法
vector mul(vector& a,int b){
    vector res;
    //进位
    int t=0;
    //如果b为0,则结果为0 不必进行乘法运算
    if(b==0) {
        res.push_back(0);
        return res;
    }
    //每一位都与b相乘
    for(int i=0;i>a>>b;
    vector A;
    //逆序存入数组
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
    auto c=mul(A,b);
    for(int i=c.size()-1;i>=0;i--) cout<

题目794:高精度除法

算法思想:

和高精度+-×法差不多,值得注意的是:
1、除法比较特殊,需要从最高位开始除数,所以for循环倒序,因为最后一位存的是最高位。
2、因为除法存在第一位是0的情况,所以要去除前导0。
3、不懂得友友可以自己手算模拟一下!很清晰!

代码实现:O(n)

#include 
#include 
#include 
#include 
using namespace std;
vector div(vector &a, int b, int &r)
{
    vector res;
    // 除法需要从最高位开始算
    for (int i = a.size() - 1; i >= 0; i--)
    {
        // 余数操作
        r = r * 10 + a[i];
        // 存入商
        res.push_back(r / b);
        // 更新余数
        r = r % b;
    }
    // 反转数组 去除多余的前导0  因为除法第一个数一定是0
    reverse(res.begin(), res.end());
    while (res.size() > 1 && res.back() == 0)
        res.pop_back();
    return res;
}
int main()
{
    string a;
    int b;
    cin >> a >> b;
    vector A;
    // 反转存入数组
    for (int i = a.size() - 1; i >= 0; i--)
        A.push_back(a[i] - '0');
    // 余数
    int r = 0;
    auto c = div(A, b, r);
    for (int i = c.size() - 1; i >= 0; i--)
        cout << c[i];
    cout << endl
         << r << endl;
    return 0;
}

欢迎友友评论区讨论,有不足请指出,大家一起交流进步!

posted on 2025-10-25 22:10  lxjshuju  阅读(1)  评论(0)    收藏  举报