【比赛链接】
【题解链接】
【A】 Limited Insertion
【思路要点】
- 考虑时间倒流,对于一个位置 i i i ,若 a i = i a_i=i ai=i ,则可以将其删去,问是否能将序列删空。
- 不难发现每次删除最大的 i i i ,使得 a i = i a_i=i ai=i 是唯一的最优策略,模拟之,若无法操作则无解。
- 时间复杂度 O ( N 2 ) O(N^2) O(N2) 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 2e5 + 5; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) { x = max(x, y); } template <typename T> void chkmin(T &x, T y) { x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int n, a[MAXN], ans[MAXN]; int main() { read(n); for (int i = 1; i <= n; i++) read(a[i]); for (int i = n; i >= 1; i--) { int pos = 0; for (int j = 1; j <= i; j++) if (a[j] == j) pos = j; if (pos == 0) { puts("-1"); return 0; } ans[i] = pos; for (int j = pos; j < i; j++) a[j] = a[j + 1]; } for (int i = 1; i <= n; i++) writeln(ans[i]); return 0; }
【B】 Balanced Neighbors
【思路要点】
- 考虑构成一张完全图,再删去若干条边使其合法。
- 若 N N N 为奇数,可以删去边 1 − ( N − 1 ) , 2 − ( N − 2 ) . . . 1-(N-1),2-(N-2)... 1−(N−1),2−(N−2)... 。
- 若 N N N 为偶数,可以删去边 1 − N , 2 − ( N − 1 ) . . . 1-N,2-(N-1)... 1−N,2−(N−1)... 。
- 不难发现剩余的图一定也是连通的。
- 时间复杂度 O ( N 2 ) O(N^2) O(N2) 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 2e5 + 5; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) { x = max(x, y); } template <typename T> void chkmin(T &x, T y) { x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int n; vector <pair <int, int>> a; int main() { read(n); for (int i = 1; i <= n; i++) for (int j = i + 1; j <= n; j++) if (i + j != n + (n + 1) % 2) a.emplace_back(i, j); writeln(a.size()); for (auto x : a) printf("%d %d\n", x.first, x.second); return 0; }
【C】 Three Circuits
【思路要点】
- 首先,若这张图不是一张欧拉图,答案为 N o No No ,下令各点度数为偶数。
- 若存在一个点度数 ≥ 6 \geq 6 ≥6 ,该点将在欧拉回路上出现至少 3 3 3 次,我们可以将该欧拉回路分成 3 3 3 部分,答案为 Y e s Yes Yes ,下令各点度数 ∈ { 2 , 4 } \in \{2,4\} ∈{ 2,4} ,记度为 4 4 4 的点数为 c n t 4 cnt_4 cnt4 。
- 若 c n t