Codeforces Round #727 (Div. 2) A~D題題解
阿新 • • 發佈:2021-07-07
比賽連結:Here
1539A. Contest Start
讓我們找出哪些參與者會干擾參與者i。這些是數字在 \(i+1\) 和 \(i+min(t/x,n)\)之間的參與者。所以第一個最大值 \((0,n−t/x)\) 參與者將獲得 \(t/x\) 不滿意,下一個參與者將比上一個參與者少獲得 \(1\) 個不滿意。所以總的答案是 \(max(0,n−(t/x)⋅t/x+min(n−1,t/x−1)⋅min(n,t/x)/2\)。
int main() { cin.tie(nullptr)->sync_with_stdio(false); int _; for (cin >> _; _--;) { ll n, x, t; cin >> n >> x >> t; ll ans = 0; if (n > t / x) { ans = (n - t / x) * (t / x); t /= x; ans += t * (t - 1) / 2; } else ans = n * (n - 1) / 2 ; cout << ans << "\n"; } }
1539B. Love Song
偽裝成字串的字首和
【AC Code】
int main() { cin.tie(nullptr)->sync_with_stdio(false); int n, q; string s; cin >> n >> q >> s; vector<int>pre(n + 1); for (int i = 0; i < n; ++i) pre[i + 1] = pre[i] + (int)(s[i] - 'a' + 1); while (q--) { int l, r; cin >> l >> r; cout << pre[r] - pre[l - 1] << "\n"; } }
1539C. Stable Groups
給定 \(n\) 個數和 \(k,x\) 兩個正整數,現有 \(n\) 個分值為 \(a_i\) 的學生,要求排列後相鄰兩個學生的差的絕對值不大於x,至多能在序列中插入k個任意分值的學生,最少能把原序列加上新的學生後(可不全加或不加)分為幾個滿足條件的子序列。
一開始覺得可以寫反悔貪心(的確也可以),但模擬的過程發現對兩個排序以後的相鄰數差值再排序的結果即答案。
即按升序補學生
【AC Code】
int main() { cin.tie(nullptr)->sync_with_stdio(false); ll n, k, x; cin >> n >> k >> x; vector<ll>a(n); for (ll &x : a)cin >> x; sort(a.begin(), a.end()); vector<ll>b(n - 1); for (int i = 0; i < n - 1; ++i) b[i] = max(0ll, (a[i + 1] - a[i] - 1) / x); sort(b.begin(), b.end()); ll cnt = n; for (int i = 0; i < n - 1; ++i) { if (b[i] <= k) { k -= b[i]; cnt--; } } cout << cnt << "\n"; }
1539D. PriceFixed
要買 \(n\) 種商品,每種商品要買 \(a_i\) 個,每種商品在購買過 \(b_i\) 件任意商品後可以打五折,每件商品原價為2,最少需要多少錢。
很明顯單純為了打折而去買多的商品至少需要1+1元,和直接買沒區別,那就是直接貪心了。
【AC Code】
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin >> n;
vector<pair<ll, ll>> v(n);
for (int i = 0; i < n; ++i) {
cin >> v[i].second >> v[i].first;
}
sort(v.begin(), v.end());
int il = 0;
int ir = n - 1;
ll have = 0;
ll ans = 0;
while (il <= ir) {
while (il <= ir && v[il].first <= have) {
ans += v[il].second;
have += v[il].second;
v[il].second = 0;
++il;
}
while (ir >= il && v[ir].second == 0)
--ir;
if (il > ir) break;
ll cnt = min(v[il].first - have, v[ir].second);
v[ir].second -= cnt;
have += cnt;
ans += cnt * 2;
}
cout << ans << '\n';
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n; cin >> n;
vector<ll>a(n), b(n);
for (int i = 0; i < n; ++i) {
cin >> a[i] >> b[i];
}
ll total = accumulate(a.begin(), a.end(), 0ll);
ll ans = 2 * total;
vector<ll>order(n);
iota(order.begin(), order.end(), 0); // 生從 0 到 N 的連續整數,即 0、1、2、3、……、N。
sort(order.begin(), order.end(), [&] (int i, int j) {
return b[i] > b[j];
});
ll cnt = total;
for (ll i : order) {
ll tmp = max(0ll, min(cnt - b[i], a[i]));
ans -= tmp;
cnt -= tmp;
}
cout << ans << '\n';
}
The desire of his soul is the prophecy of his fate
你靈魂的慾望,是你命運的先知。