Educational Codeforces Round 172 (Rated for Div. 2) 赛事记录
又要熬夜.
A. Greedy Monocarp
题意
你有 \(n\) 个箱子, 每个箱子最初有 \(a_i\) 个硬币.
现在有一个人, 他会贪心地按硬币多少从大到小拿箱子, 最终使得总共拿取的数量至少为 \(k\).
你现在想要他拿最少的硬币, 所以需要向里面添加硬币.
求必须添加的最少数量.
思路
贪心板子题.
我们先让其从大往小拿箱子, 直到剩余所需硬币数量小于箱子内的硬币个数为止.
这个剩余所需硬币数量即为答案.
#include "iostream"
#include "algorithm"
using namespace std;
constexpr int N = 52;
int n, k, a[N];
void init()
{
cin >> n >> k;
for (int i = 1; i <= n; ++i)
cin >> a[i];
sort(a + 1, a + n + 1);
return;
}
void calculate()
{
int tot = k, pos = n;
while (1)
{
if (tot < a[pos] or pos == 0)
break;
tot -= a[pos];
--pos;
}
cout << tot << '\n';
return;
}
void solve()
{
init();
calculate();
}
int main()
{
int T;
cin >> T;
while (T--)
solve();
return 0;
}
T2
题意
如图.

思路
依旧贪心板子题.
考虑 Alice, 对其来说一定是先选数量少的弹珠更优(因为更有可能集齐).
而对于 Bob, 他想破坏 Alice 的计划, 所以他一定会尽可能地使 Alice 集不齐一种颜色.
而 Alice 是先手, 所以对于数量为一的弹珠, 她一定可以取到.
这样, 容易发现, 最优策略即为排序后隔一个取一个.
模拟即可.
#include "iostream"
#include "algorithm"
using namespace std;
constexpr int N = 1e3 + 10;
int n, a[N], cnt[N];
bool vis[N];
void init()
{
cin >> n;
for (int i = 1; i <= n; ++i)
cnt[i] = vis[i] = 0;
for (int i = 1; i <= n; ++i)
cin >> a[i], ++cnt[a[i]];
sort(a + 1, a + n + 1, [](int x, int y)
{ return cnt[x] == cnt[y] ? x < y : cnt[x] < cnt[y]; });
return;
}
void calculate()
{
int ans = 0;
for (int i = 1; i <= n; i += 2)
{
if (cnt[a[i]] == 1 and !vis[a[i]])
++ans;
if (!vis[a[i]])
++ans, vis[a[i]] = 1;
}
cout << ans << '\n';
return;
}
void solve()
{
init();
calculate();
}
int main()
{
int T;
cin >> T;
while (T--)
solve();
return 0;
}
T3
题意
思路
考虑最终贡献:
\[(cnt1_{x_1} - cnt0_{x_1}) \times 0 + ((cnt1_{x_2} - cnt1_{x_1}) - (cnt0_{x_2} - cnt0_{x_1})) \times 1 + ... + ((cnt1_{x_n} - cnt1_{x_{n-1}}) - (cnt0_{x_n} - cnt0_{x_{n-1}})) \times (n - 1)
\]
\(cnt_1,\ cnt_0\) 即为前 \(i\) 为 1, 0 的个数.
展开化简得:
\[(cnt0_{x_1}-cnt1_{x_1})+(cnt0{x_2}-cnt1{x_2})+...+(cnt0_{x_{n-1}}-cnt1{x_{n-1}})+(n-1) \times (cnt1_{x_n}-cnt0_{x_n})
\]
最后的 \((cnt1_{x_n}-cnt0_{x_n})\) 为定值, 先不考虑.
可以发现每一对括号内的 \(x_i\) 是互不影响的, 所以我们可以从大到小贪心地取(将 \((cnt0_{x_i}-cnt1_{x_i})\) 看做一个整体).
这样就又变成了贪心板子题.
#include "iostream"
#include "algorithm"
#include "numeric"
#include "cstring"
using namespace std;
constexpr int N = 2e5 + 10;
int n, k;
string s;
int cnt0[N], cnt1[N];
int f[N];
void init()
{
memset(cnt0, 0, sizeof cnt0);
memset(cnt1, 0, sizeof cnt1);
cin >> n >> k;
cin >> s, s = " " + s;
for (int i = 1; i <= n; ++i)
{
cnt0[i] = cnt0[i - 1] + (s[i] == '0');
cnt1[i] = cnt1[i - 1] + (s[i] == '1');
}
iota(f + 1, f + n + 1, 1);
sort(f + 1, f + n + 1, [](int x, int y)
{
int dx=cnt0[x]-cnt1[x],dy=cnt0[y]-cnt1[y];
if (dx==dy)
return x<y;
return dx>dy;
});
return;
}
void calculate()
{
int tot = 0, pos = 1;
while (1)
{
if (tot >= k or pos == n + 1)
break;
tot += cnt0[f[pos]] - cnt1[f[pos]];
tot += cnt1[n] - cnt0[n];
++pos;
}
if (pos == n + 1)
pos = -1;
cout << pos << '\n';
return;
}
void solve()
{
init();
calculate();
}
int main()
{
int T;
cin >> T;
while (T--)
solve();
return 0;
}
T4
题意

思路
排序 + 二分查找.
#include "iostream"
#include "algorithm"
#include "set"
using namespace std;
constexpr int N = 2e5 + 10;
int n;
struct Node
{
int l, r;
int id;
friend bool operator<(Node x, Node y)
{
if (x.l ^ y.l)
return x.l < y.l;
return x.r > y.r;
}
} a[N];
long long ans[N];
void init()
{
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> a[i].l >> a[i].r;
a[i].id = i, ans[i] = 0;
}
return;
}
set<int> s;
void calculate()
{
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; ++i)
{
auto it = s.lower_bound(a[i].r);
if (it != s.end())
ans[a[i].id] += (*it) - a[i].r;
s.insert(a[i].r);
}
s.clear();
for (int i = 1; i <= n; ++i)
{
a[i].l = 1e9 - a[i].l;
a[i].r = 1e9 - a[i].r;
swap(a[i].l, a[i].r);
}
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; ++i)
{
auto it = s.lower_bound(a[i].r);
if (it != s.end())
ans[a[i].id] += (*it) - a[i].r;
s.insert(a[i].r);
}
s.clear();
for (int i = 1; i ^ n; ++i)
{
if (a[i].l == a[i + 1].l and a[i].r == a[i + 1].r)
ans[a[i].id] = ans[a[i + 1].id] = 0;
}
for (int i = 1; i <= n; ++i)
cout << ans[i] << '\n';
return;
}
void solve()
{
init();
calculate();
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T;
cin >> T;
while (T--)
solve();
return 0;
}
后补.

浙公网安备 33010602011771号