Codeforces Round #579 (Div. 3)
比赛链接:https://codeforces.com/contest/1203
A - Circle of Students
题意
$n$ 个数的一种排列组成一个环,问能否顺时针或逆时针可以从 $1$ 依次走到 $n$ 。
题解一
记录 $1$ 的位置,从该位置出发顺、逆时针各走 $n-1$ 次,看是否有一次满足题意。
代码一
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; int a[n] = {}; int pos = -1; for (int i = 0; i < n; i++) { cin >> a[i]; if (a[i] == 1) { pos = i; } } bool okl = true, okr = true; for (int i = 1; i < n; i++) { okl &= (a[(pos - i + n) % n] == i + 1); okr &= (a[(pos + i + n) % n] == i + 1); } cout << (okl or okr ? "YES" : "NO") << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
题解二
根据前两个元素的大小判断应为递增序还是递减序。
代码二
#include <bits/stdc++.h> #define nx(x) (x + 1) % n #define pre(x) (x - 1 + n) % n using namespace std; void solve() { int n; cin >> n; int a[n] = {}; for (int i = 0; i < n; i++) cin >> a[i], --a[i]; if (n == 1) { cout << "YES\n"; return; } if (a[1] == (a[0] + 1) % n) { for (int i = 0; i < n; i++) { if (a[i] != (a[pre(i)] + 1) % n) { cout << "NO\n"; return; } } cout << "YES\n"; } else { for (int i = 0; i < n; i++) { if (a[i] != (a[pre(i)] - 1 + n) % n) { cout << "NO\n"; return; } } cout << "YES\n"; } } int main() { int t; cin >> t; while (t--) solve(); }
B - Equal Rectangles
题意
有 $4n$ 条边,问这些边能否组成 $n$ 个相同的矩形。
题解
先把边按大小排序,然后每次从两端各取两边,先判断同一端的两边是否相等,然后判断它们的面积是否为定值。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; int a[4 * n] = {}; for (auto &i : a) cin >> i; sort(a, a + 4 * n); int area = a[0] * a[4 * n - 1]; bool ok = true; for (int i = 0; i < n; i++) { int l = 2 * i, r = 4 * n - 1 - 2 * i; if (a[l] != a[l + 1] or a[r] != a[r - 1] or a[l] * a[r] != area) ok = false; } cout << (ok ? "YES" : "NO") << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
C - Common Divisors
题意
找出 $n$ 个数有多少个共同因子。
题解
求 $n$ 个数 $gcd$ 的因子个数即可。
代码
#include <bits/stdc++.h> using LL = long long; using namespace std; int main() { int n; cin >> n; LL gcd = 0; for (int i = 0; i < n; i++) { LL x; cin >> x; gcd = __gcd(x, gcd); } int ans = 0; for (LL i = 1; i * i <= gcd; i++) { if (gcd % i == 0) ans += (i * i == gcd ? 1 : 2); } cout << ans; }
D2. Remove the Substring (hard version)
题意
给定字符串 $s$ 和 $t$,$t$ 为 $s$ 的一个子序列,要求从 $s$ 中移除一个连续子串后 $t$ 仍为余下字符串的子序列,问可移除连续子串的最大长度。
题解
待填。
E - Boxers
题意
有 $n$ 个正整数,每个数改变前后之差的绝对值至多为 $1$,不可以减为 $0$,问这 $n$ 个数最多能有多少个不同的数。
题解
贪心,和 CF1283E 类似。
代码
#include <bits/stdc++.h> using namespace std; int main() { int n; cin >> n; int a[n] = {}; for (auto &i : a) cin >> i; sort(a, a + n); map<int, bool> vis; vis[0] = true; for (int i = 0; i < n; i++) { if (!vis[a[i] - 1]) a[i] = a[i] - 1; else if (!vis[a[i]]) a[i] = a[i]; else if (!vis[a[i] + 1]) a[i] = a[i] + 1; vis[a[i]] = true; } cout << vis.size() - 1 << "\n"; }

浙公网安备 33010602011771号