A. Doors in the Center
模拟
代码实现
n = int(input())
s = ['-']*n
if n%2 == 0:
s[n//2-1] = '='
s[n//2] = '='
else:
s[n//2] = '='
print(''.join(s))
B. Full House 3
爆搜,或者统计每种数出现的次数,次数最多的数对应的次数应该至少是 \(3\),次数第二多的数对应的次数应该至少是 \(2\)
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n = 7;
vector<int> a(n);
rep(i, n) cin >> a[i];
ranges::sort(a);
do {
if (a[0] != a[1]) continue;
if (a[1] == a[2]) continue;
if (a[2] != a[3]) continue;
if (a[3] != a[4]) continue;
puts("Yes");
return 0;
} while (next_permutation(a.begin(), a.end()));
puts("No");
return 0;
}
// 法2:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n = 7;
vector<int> a(n);
rep(i, n) cin >> a[i];
int m = 13;
vector<int> cnt(m+1);
for (int x : a) cnt[x]++;
ranges::sort(cnt, greater<>());
if (cnt[0] >= 3 and cnt[1] >= 2) puts("Yes");
else puts("No");
return 0;
}
C. Uniqueness
统计每种数的出现次数
需要注意的是,这里求的是值最大的数对应的下标,不一定是最大下标
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n);
rep(i, n) cin >> a[i];
unordered_map<int, int> cnt;
rep(i, n) cnt[a[i]]++;
int mx = -1, ans = -1;
rep(i, n) {
if (cnt[a[i]] >= 2) continue;
if (mx < a[i]) {
mx = a[i];
ans = i+1;
}
}
cout << ans << '\n';
return 0;
}
D. Bonfire
可以理解为,不是烟雾在移动,而是高桥和篝火在移动,那么它们的移动方向就和原先烟雾的移动方向反过来
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using P = pair<int, int>;
int main() {
int n, R, C;
string s;
cin >> n >> R >> C >> s;
int r = 0, c = 0;
set<P> smokes;
smokes.emplace(0, 0);
string ans;
rep(i, n) {
if (s[i] == 'N') r++;
if (s[i] == 'S') r--;
if (s[i] == 'W') c++;
if (s[i] == 'E') c--;
smokes.emplace(r, c);
int tr = r+R, tc = c+C;
if (smokes.count(P(tr, tc))) ans += '1'; else ans += '0';
}
cout << ans << '\n';
return 0;
}
E. Tree Game
这题的关键在于“没奇环等价于二分图,而树是二分图”!如果两边的集合大小分别是 \(x\) 和 \(y\),那么最终的边数就是 \(xy\) 条。这样一来,就可以知道还需要添加多少条边才会结束,进而根据边数的奇偶性来决定先手还是后手!
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using P = pair<int, int>;
int main() {
int n;
cin >> n;
vector<vector<int>> to(n);
vector<P> es;
rep(i, n-1) {
int a, b;
cin >> a >> b;
--a; --b;
to[a].push_back(b);
to[b].push_back(a);
es.emplace_back(a, b);
}
vector<vector<int>> vs(2);
auto dfs = [&](auto& f, int v, int c=0, int p=-1) -> void {
vs[c].push_back(v);
for (int u : to[v]) {
if (u == p) continue;
f(f, u, c^1, v);
}
};
dfs(dfs, 0);
set<P> cand;
for (int a : vs[0]) for (int b : vs[1]) {
cand.emplace(min(a, b), max(a, b));
}
for (auto e : es) cand.erase(e);
int me = false;
if (cand.size()%2) me = true;
if (me) cout << "First" << endl;
else cout << "Second" << endl;
while (1) {
if (me) {
auto it = cand.begin();
auto [a, b] = *it;
cand.erase(it);
a++; b++;
cout << a << ' ' << b << endl;
}
else {
int a, b;
cin >> a >> b;
if (a == -1) break;
--a; --b;
cand.erase(P(a, b));
}
me = !me;
}
return 0;
}
F. ABCBA
经典题
其实就是找后缀最长的回文
力扣上有一堆做法 LC214
比较简单的做法是哈希和 \(Z\) 算法
讲一下 \(Z\) 算法的这种做法
令 \(rs\) 为 \(s\) 做翻转后的字符串,\(t = rs+s\)
当 \(Z[n+i] = n-i+1\) 时,\(s\) 中后 \(n-i+1\) 个字符构成回文
代码实现
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
string s;
cin >> s;
int n = s.size();
string t = s;
ranges::reverse(t);
t += s;
vector<int> z = z_algorithm(t);
rep(i, n) {
if (z[n+i] == n-i) {
string ans = s;
ans += t.substr(n-i, i);
cout << ans << '\n';
return 0;
}
}
return 0;
}
浙公网安备 33010602011771号