Codeforces Round 1046 (Div. 2) ABCD
比赛🔗 Codeforces Round 1046 (Div. 2)
A. In the Dream
在一个半场中,最坏情况下胜负情况是 $AABAABAA$ 这种形式。设分数较小的是 $x$ ,那么另外一个人的得分满足 $y \le 2x + 2$
void solve() {
int a, b, c, d;
cin >> a >> b >> c >> d;
auto check = [&](int a, int b) -> bool {
if (a > b)
swap(a, b);
return 2 * a + 2 >= b;
};
if (check(a, b) && check(c - a, d - b))
YES();
else
NO();
}
B. Like the Bitset
要求不能有连续的 $k$ 个 1. 构造的时候,先填 0 的位置,尽可能填比较大的数字,剩下的数字填在 1 的位置。
void solve() {
int n, k;
cin >> n >> k;
string s;
cin >> s;
s = " " + s;
int cur = 0, cnt = 0;
bool ok = true;
VI zeros, ones;
For1(i, 1, n) {
if (s[i] == '1') {
cur++;
ones.pb(i);
} else {
cur = 0;
zeros.pb(i);
}
ckmax(cnt, cur);
if (cnt >= k) {
ok = false;
break;
}
}
if (!ok) {
NO();
return;
}
int idx = n;
VI ans(n + 1);
for (auto x : zeros) {
ans[x] = idx--;
}
for (auto x : ones) {
ans[x] = idx--;
}
YES();
For1(i, 1, n) { cout << ans[i] << ' '; }
cout << '\n';
}
C. Against the Difference
设状态 $d_i$ 表示前 $i$ 个位置,最长合法子序列的长度。我们记录每个数字的位置到数组 $b$ 中, $b[x]$ 是 $x$ 出现过的位置的数组。对于位置 $i$ ,如果 $b_{a_i}$ 的长度不小于 $a_i$ ,那么状态转移到 $d_{pre - 1}$ 其中 $pre = b[x][len - a_i]$
void solve() {
int n;
cin >> n;
VI a(n + 1);
For1(i, 1, n) cin >> a[i];
VI d(n + 1);
VVI b(n + 1);
int ans = 0;
For1(i, 1, n) {
int x = a[i];
b[x].pb(i);
int len = SZ(b[x]);
if (len >= x) {
int pre = b[x][len - x];
ckmax(d[i], d[pre - 1] + x);
}
ckmax(d[i], d[i - 1]);
ckmax(ans, d[i]);
}
cout << ans << '\n';
}
D. For the Champion
给定的式子 $min(|x_i - c| + |y_i - d|)$ 中的绝对值不好处理。考虑如何去掉绝对值。
从起始位置移动到右下角到 $c_1 = c + 2U, d_1 = d - 2U$ , 其中 $U = 10^9$ . 这样可以保证 $(c_1, d_1)$ 一定在所有点的右下方。
同理,从起始位置移动到右上角 $c_2 = c + 2U, d_2 = d + 2U$ , 其中 $U = 10^9$ . 这样可以保证 $(c_2, d_2)$ 一定在所有点的右上方。
然后可以根据对 $(c_1, d_1)$ 和 $(c_2, d_2)$ 的询问,得到不带绝对值的式子对应的答案。得到二元一次方程组。
void solve() {
int n;
cin >> n;
vector<PII> a(n + 1);
int sub = 2e9 + 10, add = -2e9 - 10;
For1(i, 1, n) {
cin >> a[i].first >> a[i].second;
ckmin(sub, a[i].second - a[i].first);
ckmax(add, a[i].first + a[i].second);
}
auto query = [&](char ch, int k) -> ll {
cout << "? " << ch << ' ' << k << endl;
ll dis;
cin >> dis;
return dis;
};
int U = 1e9;
query('R', U);
query('R', U);
query('D', U);
ll val1 = query('D', U);
query('U', U);
query('U', U);
query('U', U);
ll val2 = query('U', U);
ll t = 1LL * val2 + add - 4LL * U, s = 1LL * val1 - sub - 4LL * U;
ll x = (t + s) / 2, y = t - x;
cout << "! " << x << ' ' << y << endl;
}
