社区讨论

WA求救

P13298 [GCJ 2013 #3] Cheaters参与者 2已保存回复 1

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@mhjd4wyb
此快照首次捕获于
2025/11/04 00:37
4 个月前
此快照最后确认于
2025/11/04 00:37
4 个月前
查看原帖
CPP
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
#include <set>

using namespace std;

typedef long long ll;

ll B(int i, ll h, const vector<ll>& A, const vector<ll>& P) {
    ll cost1 = (ll)i * h - P[i];
    ll cost2 = 0;
    for (int j = i; j < 37; j++) {
        if (h + 1 > A[j]) {
            cost2 += (h + 1 - A[j]);
        }
    }
    return cost1 + cost2;
}

int main() {
    int T;
    cin >> T;
    vector<string> results;
    for (int t = 0; t < T; t++) {
        ll M;
        cin >> M;
        vector<ll> bets(37);
        for (int i = 0; i < 37; i++) {
            cin >> bets[i];
        }
        sort(bets.begin(), bets.end());
        vector<ll> P(38, 0);
        for (int i = 1; i <= 37; i++) {
            P[i] = P[i-1] + bets[i-1];
        }
        double best_profit = 0.0;
        for (int i = 1; i <= 37; i++) {
            ll h_min = bets[i-1];
            ll cost_at_min = B(i, h_min, bets, P);
            if (cost_at_min > M) {
                continue;
            }
            ll low = h_min;
            ll high = h_min;
            while (true) {
                ll current_cost = B(i, high, bets, P);
                if (current_cost <= M) {
                    low = high;
                    if (high == 0) {
                        high = 1;
                    } else {
                        high *= 2;
                        if (high > 1e18) {
                            break;
                        }
                    }
                } else {
                    break;
                }
            }
            ll left = low;
            ll right = high;
            ll h_max = low;
            while (left <= right) {
                ll mid = (left + right) / 2;
                if (B(i, mid, bets, P) <= M) {
                    h_max = mid;
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
            set<ll> candidates;
            candidates.insert(h_min);
            candidates.insert(h_max);
            for (int j = i; j < 37; j++) {
                ll candidate_h = bets[j] - 1;
                if (candidate_h >= h_min && candidate_h <= h_max) {
                    candidates.insert(candidate_h);
                }
            }
            for (ll h : candidates) {
                if (h < h_min) continue;
                ll total_cost = B(i, h, bets, P);
                if (total_cost > M) continue;
                ll B_min = (ll)i * h - P[i];
                ll F_val = 0;
                for (int j = i; j < 37; j++) {
                    if (h + 1 > bets[j]) {
                        F_val += (h + 1 - bets[j]);
                    }
                }
                double profit = B_min * (36.0 / i - 1) - F_val;
                if (profit > best_profit) {
                    best_profit = profit;
                }
            }
        }
        results.push_back(to_string(best_profit));
    }
    for (const string& res : results) {
        size_t dot_pos = res.find('.');
        if (dot_pos != string::npos) {
            string integer_part = res.substr(0, dot_pos);
            string decimal_part = res.substr(dot_pos + 1);
            if (decimal_part.length() < 10) {
                decimal_part += string(10 - decimal_part.length(), '0');
            } else {
                decimal_part = decimal_part.substr(0, 10);
            }
            cout << integer_part << "." << decimal_part << endl;
        } else {
            cout << res << ".0000000000" << endl;
        }
    }
    return 0;
}

回复

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

正在加载回复...