社区讨论
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 条回复,欢迎继续交流。
正在加载回复...