Educational Codeforces Round 77 (Rated for Div. 2) A~E
A. Heating
#include<bits/stdc++.h>
int dp[1000010], idx;
void solve()
{
int c, s;
std::cin >> c >> s;
int x = s / c;
std::cout << (c - s % c) * x * x + (x + 1) * (x + 1) * (s % c) << "\n";
}
int main()
{
std::ios::sync_with_stdio(0);
std::cin.tie(0), std::cout.tie(0);
int T;
T = 1;
std::cin >> T;
while (T--) solve();
return 0;
}
B. Obtain Two Zeroes
#include<bits/stdc++.h>
void solve()
{
int a, b;
std::cin >> a >> b;
if (a > b) std::swap(a, b);
if (a * 2 < b || (a + b) % 3) {std::cout << "NO" << "\n";}
else {std::cout << "YES\n";}
}
int main()
{
int T;
std::cin >> T;
while (T--) solve();
return 0;
}
C. Infinite Fence
#include<bits/stdc++.h>
#define i64 long long
void solve()
{
i64 r, g, k;
std::cin >> r >> g >> k;
i64 gcd = std::__gcd(r, g);
r /= gcd;
g /= gcd;
if (r > g) std::swap(r, g);
if (r * (k - 1) + 1 >= g) std::cout << "OBEY\n";
else std::cout << "REBEL\n";
}
int main()
{
int T;
std::cin >> T;
while (T--) solve();
return 0;
}
D. A Game with Traps
题意:给出m个士兵,长度为n的路,k个从
[
l
,
r
]
,威胁为
x
[l,r],威胁为x
[l,r],威胁为x的陷阱,总共t秒的时间,现在每个士兵有自己的等级,士兵等级大于等于陷阱威胁就不会被杀死,现在你要带领最多的士兵走到n+1,你可以自己走到陷阱的终点去解除陷阱,走一步的代价是1。
思路:很容易想到的是二分,然后我们对有威胁的路段打上标记,对于有标记的路段,我们每一步需要花费3的时间,因为我们要走过去解除陷阱,走回来带士兵走过去,所以是3的代价。
#include<bits/stdc++.h>
int a[200010];
int main()
{
int n, m, k, t;
std::cin >> m >> n >> k >> t;
std::vector<int> L(k + 2), R(k + 2), x(k + 2);
for (int i = 1; i <= m; i++) std::cin >> a[i];
for (int i = 1; i <= k; i++) {
std::cin >> L[i] >> R[i] >> x[i];
}
std::sort(a + 1, a + 1 + m, std::greater<int>());
std::function<bool(int)>check = [&](int mid){
std::vector<int> st(n + 2);
int maxn = a[mid];
for (int i = 1; i <= k; i++) {
if (x[i] > maxn) {st[L[i]]++; st[R[i] + 1]--;}
}
int sum = 0;
for (int i = 1; i <= n + 1; i++) {
st[i] = st[i] + st[i - 1];
if (st[i]) sum += 3;
else sum += 1;
}
return sum <= t;
};
int l = 0, r = m + 1;
while (l < r) {
int mid = l + r >> 1;
if (check(mid)) l = mid + 1;
else r = mid;
}
std::cout << std::max(0, l - 1);
return 0;
}
E. Tournament
题意:给出n个人,保证n是二的幂次方,会进行很多轮比赛,每轮比赛两两配对,编号大的赢,但是可以贿赂编号大的,让他输掉,输出最小花费
思路:肯定是从n开始往前考虑,因为比-1小的都可以赢,然后最多贿赂log个人,因为每次少一半,然后从后往前考虑,因为这样可以保证我贿赂到的人一定是可以赢后面的人,每到2的幂次方我们就贿赂最小花费的人
#include<bits/stdc++.h>
#define int long long
signed main()
{
int n;
std::cin >> n;
std::vector<int>a(n + 1);
int ans = 0;
std::priority_queue<int, std::vector<int>, std::greater<int> > Q;
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
}
for (int i = n; a[i] != -1; i--) {
Q.push(a[i]);
if (!(i & (i - 1))) {ans += Q.top(); Q.pop();}
}
std::cout << ans << "\n";
return 0;
}