高精度算法

一、 高精度加法

两数相加,注意进位
题目:A+B Problem(高精) - 洛谷

#include <bits/stdc++.h>
using namespace std;
string s1, s2;
int a[505] = {0}, b[505] = {0}, c[505] = {0}, len1, len2, zd;
int main()
{
    cin >> s1 >> s2;
    len1 = s1.size(), len2 = s2.size();
    
    // 将字符串分别翻转存入a1、a2(从个位开始加)
    for(int i = len1 - 1, j = 1; i >= 0; i--, j++)
    {
        a[j] = s1[i] - '0';
    } 
    for(int i = len2 - 1, j = 1; i >= 0; i--, j++)
    {
        b[j] = s2[i] - '0';
    }
    
    len1 > len2 ? zd = len1 : zd = len2; // 以位数多的为主
    for(int i = 1; i <= zd; i++)
    {
        c[i] += a[i] + b[i];
        c[i + 1] += c[i] / 10; // 加上进位
        c[i] %= 10; 
    } 
    
    // 可能最后会有进位
    if(c[zd + 1]) zd++; 
    for(int i = zd; i >= 1; i--)
    {
        cout << c[i];
    }
    return 0;
}

二、 高精度减法

两两相减,注意大减小,不够减要借位
题目:高精度减法 - 洛谷

#include <bits/stdc++.h>
using namespace std;
string s1, s2;
int a[20000] = {0}, b[20000] = {0}, c[20000] = {0}, len1, len2, zd, x;
int main()
{
    cin >> s1 >> s2;
    if(s1 == s2) {cout << 0; return 0;} // 相等直接输出 0 
    if(s1.size() < s2.size() || s1.size() == s2.size() && s1 < s2) 
        swap(s1, s2), cout << '-'; // 用大的减去小的 方便计算 最后加负号即可 
    len1 = s1.size(), len2 = s2.size();
    zd = max(len1, len2);
    for(int i = len1 - 1, j = 1; i >= 0; i--, j++)
    {
        a[j] = s1[i] - '0';
    }
    for(int i = len2 - 1, j = 1; i >= 0; i--, j++)
    {
        b[j] = s2[i] - '0';
    }
    
    for(int i = 1; i <= zd; i++)
    {
        // 看是否需要借位 不够减需要借一当十
        if(a[i] < b[i])
        {
            a[i] += 10, x = i + 1;
            while(a[x] == 0) a[x] = 9, x++; // 0 不够借的情况 一直后移直到找到够借的那一位 中间全部置为9 
            a[x] -= 1;  
        }
        c[i] = a[i] - b[i];
    }
    
    for(int i = zd; i >= 1; i--)
    {
        cout << c[i];
    } 
    return 0;
}

三、 高精度乘法

题目:A*B Problem - 洛谷
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
string s1, s2;
int a[2009] = {0}, b[2009] = {0}, c[5000] = {0}, len1, len2, len; 
int main()
{
    cin >> s1 >> s2;
    if(s1 == "0" || s2 == "0") {cout << 0; return 0;}  // 0乘任何数都得0 
    len1 = s1.size(), len2 = s2.size();
    for(int i = len1 - 1, j = 1; i >= 0; i--, j++)
    {
        a[j] = s1[i] - '0';
    }
    for(int i = len2 - 1, j = 1; i >= 0; i--, j++)
    {
        b[j] = s2[i] - '0';
    }
    
    for(int i = 1; i <= len1; i++)
    {
        /* 
        a * b[1], a * b[2], a * b[3]
        
        中间产物放置的位置 
        a[1] * b[1] --> 1
        a[1] * b[2] --> 2
        a[1] * b[3] --> 3
        a[2] * b[1] --> 2
        a[2] * b[2] --> 3
        a[2] * b[3] --> 4
        */
        for(int j = 1; j <= len2; j++)
        {
            c[i + j - 1] += a[i] * b[j];
        }
    }
    
    // 两数相乘得到的结果位数<=两数位数之和 
    // 处理进位 
    len = len1 + len2;
    for(int i = 1; i <= len; i++)
    {
        c[i + 1] += c[i] / 10;
        c[i] %= 10;
    } 
    
    // 去掉前导0
    while(c[len] == 0) len--; 
    for(int i = len; i >= 1; i--)
    {
        cout << c[i];
    }
    return 0;
}

四、 高精除低精

题目:A/B Problem - 洛谷

#include <bits/stdc++.h>
using namespace std;
string s;
long long a[5005] = {0}, b, c[5005] = {0}, len, yu = 0; // 余数 
int main()
{
    cin >> s >> b;
    len = s.size();
    for(int i = 0; i < len; i++)
    {
        a[i + 1] = s[i] - '0'; 
    }
    
    for(int i = 1; i <= len; i++)
    {
        c[i] = (a[i] + yu * 10) / b;
        yu = (a[i] + yu * 10) % b; 
    }
    
    // 去除前导0
    int k = 1;
    while(c[k] == 0 && k < len) k++;
    for(int i = k; i <= len; i++)
    {
        cout << c[i];    
    } 
    return 0;
}
  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值