Educational Codeforces Round 172 (Rated for Div. 2) 赛事记录
又要熬夜.
A. Greedy Monocarp
题意
你有 \(n\) 个箱子, 每个箱子最初有 \(a_i\) 个硬币.
现在有一个人, 他会贪心地按硬币多少从大到小拿箱子, 最终使得总共拿取的数量至少为 \(k\).
你现在想要他拿最少的硬币, 所以需要向里面添加硬币.
求必须添加的最少数量.
思路
贪心板子题.
我们先让其从大往小拿箱子, 直到剩余所需硬币数量小于箱子内的硬币个数为止.
这个剩余所需硬币数量即为答案.
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
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 是先手, 所以对于数量为一的弹珠, 她一定可以取到.
这样, 容易发现, 最优策略即为排序后隔一个取一个.
模拟即可.
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
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})\) 看做一个整体).
这样就又变成了贪心板子题.
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
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
题意
思路
排序 + 二分查找.
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
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;
}
后补.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步