社区讨论

本地和洛谷IDE都没问题 评测机全RE

P1018[NOIP 2000 提高组] 乘积最大参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lpb7gwtn
此快照首次捕获于
2023/11/23 21:04
2 年前
此快照最后确认于
2023/11/24 00:01
2 年前
查看原帖
代码见下
CPP
//P1018 [NOIP2000 提高组] 乘积最大
#include <iostream>
#include <list>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr ll base = 1e15;
int n, k;
double le_rat;
list<pair<string, double> > num;
double fastLog(const std::string &N)
{
    int length = N.length();
    if(length <= 4)
        return log(stod(N));
    double leadingDigits = stod(N.substr(0, min(3, length)));
    double logLeadingDigits = log(leadingDigits);
    return (length - 1) * log(10) + logLeadingDigits;
}
string strAdd(const string &strA, const string &strB)
{
    vector<ull> numA, numB, sum;
    for(int i = static_cast<int>(strA.length()); i > 0; i -= 15)
    {
        int startIndex = max(i - 15, 0);
        int length = i - startIndex;
        numA.push_back(stoull(strA.substr(startIndex, length)));
    }
    for(int i = static_cast<int>(strB.length()); i > 0; i -= 15)
    {
        int startIndex = max(i - 15, 0);
        int length = i - startIndex;
        numB.push_back(stoull(strB.substr(startIndex, length)));
    }
    int max_length = static_cast<int>(max(numA.size(), numB.size()));
    sum.resize(max_length);
    for(int i = 0; i < max_length; i++)
    {
        ull a = (i < numA.size()) ? numA[i] : 0;
        ull b = (i < numB.size()) ? numB[i] : 0;
        sum[i] = a + b;
    }
    string ret;
    for(int i = 0; i < max_length - 1; i++)
    {
        if(sum[i] >= base)
        {
            ++sum[i + 1];
            sum[i] -= base;
        }
        string part = to_string(sum[i]);
        ret = part + ret;
        if(part.length() < 15)
            ret = string(15 - part.length(), '0') + ret;
    }
    ret = to_string(sum[max_length - 1]) + ret;
    return ret;
}
string strSub(const string &strA, const string &strB)
{
    vector<ll> numA, numB, sum;
    for(int i = static_cast<int>(strA.length()); i > 0; i -= 15)
    {
        int startIndex = max(i - 15, 0);
        int length = i - startIndex;
        numA.push_back(stoll(strA.substr(startIndex, length)));
    }
    for(int i = static_cast<int>(strB.length()); i > 0; i -= 15)
    {
        int startIndex = max(i - 15, 0);
        int length = i - startIndex;
        numB.push_back(stoll(strB.substr(startIndex, length)));
    }
    int max_length = static_cast<int>(max(numA.size(), numB.size()));
    sum.resize(max_length);
    for(int i = 0; i < max_length; i++)
    {
        ll a = (i < numA.size()) ? numA[i] : 0;
        ll b = (i < numB.size()) ? numB[i] : 0;
        sum[i] = a - b;
    }
    string ret;
    for(int i = 0; i < max_length; i++)
    {
        if(sum[i] < 0 && i != max_length - 1)
        {
            --sum[i + 1];
            sum[i] += base;
        }
        string part = to_string(sum[i]);
        reverse(part.begin(), part.end());
        ret += part;
        if(part.length() < 15)
            ret += string(15 - part.length(), '0');
    }
    reverse(ret.begin(), ret.end());
    auto nonZero = ret.find_first_not_of('0');
    return nonZero != string::npos ? ret.substr(nonZero) : "0";
}
string strMulti(const string &strA, const string &strB)
{
    if(strA == "" || strA == "0" || strB == "" || strB == "0")
        return "0";
    int lenA = strA.length();
    int lenB = strB.length();
    if(lenA <= 9 && lenB <= 9)
    {
        return to_string(stoull(strA) * stoull(strB));
    }
    int max_length = max(lenA, lenB);
    int mid = max_length / 2;
    string p1 = (lenA > max_length - mid) ? strA.substr(0, max_length - mid) : "";
    string p2 = (lenA > max_length - mid) ? strA.substr(max_length - mid) : strA;
    string p3 = (lenB > max_length - mid) ? strB.substr(0, max_length - mid) : "";
    string p4 = (lenB > max_length - mid) ? strB.substr(max_length - mid) : strB;
    string z1 = strMulti(p1, p3);
    string z2 = strMulti(p2, p4);
    string z3 = strMulti(strAdd(p1, p2), strAdd(p3, p4));
    z3 = strSub(z3, z1);
    z3 = strSub(z3, z2);
    z1 += string(2 * mid, '0');
    z3 += string(mid, '0');
    string ret = strAdd(z1, z2);
    return ret;
}
void cal_rat(list<pair<string, double> >::iterator it)
{
    string a = it->first;
    string b = next(it)->first;
    if(a.empty() || b.empty())
        return;
    it->second = fastLog(a) + fastLog(b) - fastLog(a + b);
}
int main()
{
    scanf("%d%d", &n, &k);
    getchar();
    for(int i = 1; i <= n; i++)
        num.emplace_back(string(1, getchar()), 1);
    for(auto it = num.begin(); it != prev(num.end()); ++it)
        cal_rat(it);
    while(--n != k)
    {
        auto gr_it = num.begin();
        le_rat = 1;
        for(auto it = num.begin(); it != prev(num.end()); ++it)
        {
            if(it->second < le_rat)
            {
                le_rat = it->second;
                gr_it = it;
            }
        }
        gr_it->first = gr_it->first + next(gr_it)->first;
        num.erase(next(gr_it));
        cal_rat(gr_it);
        cal_rat(--gr_it);
    }
    string ans = "1";
    for(auto &frac: num)
        ans = strMulti(ans, frac.first);
    cout << ans << endl;
    return 0;
}
RE报错是:
Runtime Error. Received signal 6: Aborted / IOT trap.
大佬们求解orz

回复

1 条回复,欢迎继续交流。

正在加载回复...