CodeForces 1776C Library game

洛谷传送门

CF 传送门

orz p_b_p_b。

下文令 ai 为原题面中的 xi

拿到题目无从下手,不妨简化一下。

考虑 n=2 怎么做。不妨设 a1a2。发现若 a2m2 时 A 必胜,否则 B 必胜。

于是我们大胆猜测结论是将 a 从大到小排序后,i[2,n],aimi 时 A 必胜,否则 B 必胜。

证明是容易的。根据抽屉原理,第 i 轮开始前不包含选过的元素的极长连续段长度的最大值最小是 mi+1i=mi。因此:

  • 如果不满足 i[2,n],aimi,设 p 为使得 ap>mi 的位置,那么 A 选择长度 ap 的区间时,Bob 一定可以在这个区间内找到 [1,m]ap 等分点(即 apx 的点),这样 A 选完 [1,p] 的区间后,B 一定能获胜。
  • 否则,第 i 轮 A 随便选一个长度 =ai 的未被覆盖的区间即可。因为满足 i[2,n],aimi,所以第 i 轮一定存在一个长度 =ai 的未被覆盖的区间。

交互就直接按上面模拟即可。

code
// Problem: C. Library game
// Contest: Codeforces - SWERC 2022-2023 - Online Mirror (Unrated, ICPC Rules, Teams Preferred)
// URL: https://codeforces.com/problemset/problem/1776/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<int, int> pii;
const int maxn = 5050;
int n, m, a[maxn];
namespace Sub1 {
struct cmp {
inline bool operator () (const pii &a, const pii &b) {
return a.scd - a.fst > b.scd - b.fst;
}
};
void solve() {
puts("Alessia");
fflush(stdout);
multiset<pii, cmp> st;
st.emplace(1, m);
for (int i = 1; i <= n; ++i) {
pii p = *st.begin();
int l = p.fst, r = p.scd;
st.erase(st.begin());
printf("%d %d\n", a[i], l);
fflush(stdout);
int x;
scanf("%d", &x);
if (l < x) {
st.emplace(l, x - 1);
}
if (x < r) {
st.emplace(x + 1, r);
}
}
}
}
namespace Sub2 {
bool vis[maxn];
void solve() {
puts("Bernardo");
fflush(stdout);
int p = -1;
for (int i = 1; i <= n; ++i) {
if (a[i] > m / i) {
p = i;
break;
}
}
for (int i = 1, l, r; i <= n; ++i) {
scanf("%d%d", &r, &l);
r += l - 1;
int len = r - l + 1;
if (len < a[p]) {
printf("%d\n", l);
fflush(stdout);
vis[l] = 1;
continue;
}
for (int j = l; j <= r; ++j) {
if (j % a[p] == 0) {
printf("%d\n", j);
fflush(stdout);
vis[j] = 1;
break;
}
}
}
}
}
void solve() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
sort(a + 1, a + n + 1, greater<int>());
bool flag = 1;
for (int i = 1; i <= n; ++i) {
if (a[i] > m / i) {
flag = 0;
break;
}
}
if (flag) {
Sub1::solve();
} else {
Sub2::solve();
}
}
int main() {
int T = 1;
// scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}
posted @   zltzlt  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示