比赛链接:https://codeforces.com/contest/1270
A. Card Game
题意
有两个人在玩卡牌游戏,规则如下:
- 共有 $n$ 张牌,值为 $1$ 到 $n$
- 两个人各出一张牌,牌大者拿走两张牌
- 手中先无牌者输掉游戏
给出一开始两个人的手牌情况(至少都有一张牌),判断第一个人能否获胜。
题解
手牌中有最大值 $n$ 者必胜。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n, k1, k2; cin >> n >> k1 >> k2; bool first_win = false; for (int i = 0; i < n; i++) { int x; cin >> x; if (x == n and i < k1) first_win = true; } cout << (first_win ? "YES" : "NO") << " "; } int main() { int t; cin >> t; while (t--) solve(); }
B. Interesting Subarray
题意
一个好数组定义如下:
- 数组中的最值差大于等于数组的大小
给出一个大小为 $n$ 的数组 $a$,试找出一个好的连续子数组。
题解
最简单的情况即好数组大小为 $2$ 。
证明
若不存在大小为 $2$ 的好数组,则 $a$ 中的相邻元素最多相差 $1$,大小为 $i$ 的连续子数组最值差最多为 $i - 1$,即不存在好数组。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; int a[n] = {}; for (int i = 0; i < n; i++) cin >> a[i]; for (int i = 1; i < n; i++) if (abs(a[i] - a[i - 1]) >= 2) { cout << "YES" << " " << i << ' ' << i + 1 << " "; return; } cout << "NO" << " "; } int main() { int t; cin >> t; while (t--) solve(); }
C. Make Good
题意
一个好数组定义如下:
- $a_1 + a_2 + dots + a_n = 2cdot(a_1 oplus a_2 oplus dots oplus a_n)$
给出一个大小为 $n$ 的非负数组 $a$,最多可向 $a$ 中添加 $3$ 个非负整数,输出一种使 $a$ 为好数组的方案。
题解
先添加 $xor = a_1 oplus a_2 oplus dots oplus a_n$ 抵消所有的异或值,之后解方程:
$sum_a + xor + x = 2x$,即 $x = sum_a + xor$ 。
代码
#include <bits/stdc++.h> using ll = long long; using namespace std; void solve() { int n; cin >> n; ll sum = 0, Xor = 0; for (int i = 0; i < n; i++) { int x; cin >> x; sum += x, Xor ^= x; } cout << 2 << " " << Xor << ' ' << sum + Xor << " "; } int main() { int t; cin >> t; while (t--) solve(); }
D. Strange Device
题意
有一个大小为 $n$ 元素值两两不同的数组 $a$ 和一个检索装置,每次可以询问 $k$ 个下标,检索装置会给出其中第 $m$ 小元素的下标和值。
给出数组 $a$ 以及 $n,k$,最多询问 $n$ 次,试找出 $m$ 的值。
题解
只考虑 $a_1 sim a_{k+1}$,第 $i$ 次询问跳过下标 $i$,则检索装置会回答 $m$ 个 $a_{m+1}$,$k+1-m$ 个 $a_{m}$,又因为数组元素值两两不同,回答的两个值中较大者出现的次数即为 $m$ 。
代码
#include <bits/stdc++.h> using namespace std; int main() { int n, k; cin >> n >> k; map<int, int> cnt; for (int i = 1; i <= k + 1; i++) { cout << "? "; for (int j = 1; j <= k + 1; j++) if (j != i) cout << j << ' '; cout << " "; int pos, val; cin >> pos >> val; ++cnt[val]; } cout << "! " << (*cnt.rbegin()).second; }