LevOJ.sln - 第四期

LevOJ平台.sln

高精度运算模板

描述

P1120 P1121 P1134 P1136 P1139 P1155 P2025 P2102 P2103

其中P1139 需要优化高精乘法,其他题目都可以套公式。

苯蒟蒻也没系统学过算法,群佬有更高级的算法一定要在评论区贴一下喵~

模板

// 高精度模板
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <cmath>
using namespace std;

int compare(string a, string b)
{
    while (a.size() > 1 && a[0] == '0')
        a.erase(0, 1);
    while (b.size() > 1 && b[0] == '0')
        b.erase(0, 1);

    if (a.size() > b.size())
        return 1;
    if (a.size() < b.size())
        return -1;

    for (size_t i = 0; i < a.size(); ++i)
    {
        if (a[i] > b[i])
            return 1;
        if (a[i] < b[i])
            return -1;
    }
    return 0;
}

// 将字符串逆序存储到数组中
vector<int> adjust(string x)
{
    vector<int> res;
    for (int i = x.size() - 1; i >= 0; i--)
        res.push_back(x[i] - '0');
    return res;
}

// 大整数除二
string div2(const string &x)
{
    string res;
    int carry = 0;
    for (int i = 0; i < (int)x.size(); i++)
    {
        int d = x[i] - '0' + carry;
        res += (d / 2) + '0';
        carry = (d % 2) * 10;
    }

    size_t pos = res.find_first_not_of('0');
    if (pos != string::npos)
        return res.substr(pos);
    else
        return "0";
}

// 高精度加法
string add(string a, string b, int scale)
{
    vector<int> A, B;
    vector<char> C;
    A = adjust(a);
    B = adjust(b);
    int carry = 0;
    for (int i = 0; i < (int)A.size() || i < (int)B.size(); i++)
    {
        if (i < (int)A.size())
            carry += A[i];
        if (i < (int)B.size())
            carry += B[i];
        C.push_back((char)(carry % scale) + '0');
        carry /= scale;
    }
    if (carry)
        C.push_back((char)carry + '0');
    reverse(C.begin(), C.end());
    return string(C.begin(), C.end());
}

// 高精度减法
string sub(string a, string b, int scale)
{
    vector<int> A, B;
    vector<char> C;
    A = adjust(a);
    B = adjust(b);
    if (compare(a, b) < 0)
    {
        swap(A, B);
        C.push_back('-');
    }
    int borrow = 0;
    for (int i = 0; i < (int)A.size(); i++)
    {
        int diff = A[i] - borrow;
        if (i < (int)B.size())
            diff -= B[i];
        if (diff < 0)
        {
            diff += scale;
            borrow = 1;
        }
        else
            borrow = 0;
        C.push_back('0' + diff);
    }
    while (C.size() > 1 && C.back() == '0')
        C.pop_back();
    if (C[0] == '-')
        reverse(C.begin() + 1, C.end());
    else
        reverse(C.begin(), C.end());
    return string(C.begin(), C.end());
}

// 高精度乘法
string mul(string a, string b, int scale)
{
    vector<int> A, B;
    vector<char> C;
    A = adjust(a);
    B = adjust(b);
    vector<int> res(A.size() + B.size(), 0);
    for (int i = 0; i < (int)A.size(); i++)
    {
        for (int j = 0; j < (int)B.size(); j++)
        {
            res[i + j] += A[i] * B[j];
            res[i + j + 1] += res[i + j] / scale;
            res[i + j] %= scale;
        }
    }
    for (int i = (int)res.size() - 1; i >= 0; i--)
        C.push_back((char)(res[i] % scale) + '0');
    reverse(C.begin(), C.end());
    while (C.size() > 1 && C.back() == '0')
        C.pop_back();
    reverse(C.begin(), C.end());
    return string(C.begin(), C.end());
}

// 高精度阶乘
string fac(int n)
{
    string C;
    C.push_back('1');
    for (int i = 2; i <= n; i++)
    {
        string temp = mul(C, to_string(i), 10);
        C = temp;
    }
    return C;
}

// 高精度取模
string mod(string a, string b, int scale)
{
    vector<int> A, B;
    vector<char> C;
    A = adjust(a);
    B = adjust(b);
    while (compare(a, b) >= 0)
    {
        a = sub(a, b, scale);
    }
    return a;
}

// 高精度快速幂
string pow(string a, string b)
{
    string C = "1";
    while (!b.empty() && b != "0")
    {
        if ((b.back() - '0') % 2 == 1)
            C = mul(C, a, 10);
        a = mul(a, a, 10);
        b = div2(b);
    }
    return C;
}

// 高精度浮点数加法
string fadd(string a, string b)
{
    string Ai = "0", Bi = "0", Af = "0", Bf = "0", Ci, Cf;
    size_t pos;

    pos = a.find('.');
    if (pos != string::npos)
    {
        Ai = a.substr(0, pos);
        Af = a.substr(pos + 1, a.size() - pos - 1);
    }
    else
        Ai = a;

    pos = b.find('.');
    if (pos != string::npos)
    {
        Bi = b.substr(0, pos);
        Bf = b.substr(pos + 1, b.size() - pos - 1);
    }
    else
        Bi = b;

    int m = max(Af.size(), Bf.size());
    Af.insert(Af.end(), m - Af.size(), '0');
    Bf.insert(Bf.end(), m - Bf.size(), '0');
    Cf = add(Af, Bf, 10);
    int carry = 0;
    if ((int)Cf.size() > m)
    {
        carry = 1;
        Cf = Cf.substr(1);
    }
    Ci = add(Ai, Bi, 10);
    Ci = add(Ci, to_string(carry), 10);
    if (Ci.size() > 1 && Ci[0] == '0')
        Ci.erase(0, Ci.find_first_not_of('0'));
    while (Cf.size() > 1 && Cf.back() == '0')
        Cf.pop_back();

    return Ci + "." + Cf;
}

// 高精度浮点数减法
string fsub(string a, string b)
{
    string Ai, Bi, Af = "0", Bf = "0", Ci, Cf;
    size_t pos;
    int neg = 0;

    pos = a.find('.');
    if (pos != string::npos)
    {
        Ai = a.substr(0, pos);
        Af = a.substr(pos + 1, a.size() - pos - 1);
    }
    else
        Ai = a;

    pos = b.find('.');
    if (pos != string::npos)
    {
        Bi = b.substr(0, pos);
        Bf = b.substr(pos + 1, b.size() - pos - 1);
    }
    else
        Bi = b;
    if (compare(Ai, Bi) < 0)
    {
        swap(Ai, Bi);
        swap(Af, Bf);
        neg = 1;
    }
    int m = max(Af.size(), Bf.size());
    Af.insert(Af.end(), m - Af.size(), '0');
    Bf.insert(Bf.end(), m - Bf.size(), '0');
    Af.insert(Af.begin(), 1, '1');
    Cf = sub(Af, Bf, 10);
    int borrow = 1;
    if ((int)Cf.size() > m)
    {
        borrow = 0;
        Cf = Cf.substr(1);
    }
    Ci = sub(Ai, Bi, 10);
    if (borrow)
        Ci = sub(Ci, to_string(borrow), 10);
    if (Ci.size() > 1 && Ci[0] == '0')
        Ci.erase(0, Ci.find_first_not_of('0'));
    while (Cf.size() > 1 && Cf.back() == '0')
        Cf.pop_back();
    if (neg)
        Ci = "-" + Ci;

    return Ci + "." + Cf;
}

int main()
{
    string a, b;
    cin >> a >> b;
    string C = pow(a, b);
    cout << C << endl;
    return 0;
}

第四期完结!

看完了点个赞再走嘛

posted @ 2025-03-21 08:43  Churk  阅读(130)  评论(0)    收藏  举报

联系

GitHub Bilibili

X

关于

© Churk

Powered by .NET 8.0 on Kubernetes