Educational Codeforces Round 163 (Rated for Div. 2) 补题记录(A~D)
A
容易发现若 \(S\) 串中 \(s_i\) 为特殊字符,则令 \(s_i=s_{i+1}\),此时 \(s_i\neq s_{i-1}\)。则找到一个 \(j\) 满足 \(s_i=s_{i+1}=s_{i+2}=\ldots=s_j\neq s_{j+1}\),则 \(s_j\) 也一定为特殊字符。
所以若 \(2\mid n\) 则构造 \(\frac{n}{2}\) 个 AAB,否则必然无解。
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main() {
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
if (n & 1)
cout << "NO\n";
else {
cout << "YES\n";
for (int i = 1; i <= n / 2; i++)
cout << "AAB";
cout << '\n';
}
}
return 0;
}
B
考虑贪心。
首先若原序列 \(a\) 就已经单调不降,那么就已经满足条件。
否则考虑按照下标从小到大来贪心。若一个数拆分成两个数之后和她前面的所有数构成了单调不降,那么就拆分;否则就不拆分。
最后判断一下拆分完之后的序列是否单调不降即可。时间复杂度为 \(O(n)\)。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 500010;
int a[N];
signed main() {
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
if (is_sorted(a + 1, a + n + 1))
cout << "YES\n";
else {
vector<int> arr;
for (int i = 1; i <= n; i++) {
int x = a[i] / 10, y = a[i] % 10;
if (x <= y && (arr.empty() || arr.back() <= x))
arr.push_back(x), arr.push_back(y);
else
arr.push_back(a[i]);
}
if (is_sorted(arr.begin(), arr.end()))
cout << "YES\n";
else
cout << "NO\n";
}
}
return 0;
}
C
考虑记忆化搜索。设 \(v_{i,j}\) 表示 \((i,j)\) 位置有没有被访问过。每一次搜索的时候遍历和当前格子四连通的格子,判断一下是否可到达 \((2,n)\) 即可。时间复杂度为 \(O(n)\)。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 500010;
int a[N], n;
char s[4][N];
bool v[4][N];
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
void dfs(int u, int v) {
if (::v[u][v]) return;
::v[u][v] = true;
if (::v[2][n]) return;
for (int d = 0; d < 4; d++) {
int x = u + dx[d], y = v + dy[d];
if (x <= 0 || x > 2 || y <= 0 || y > n) continue;
if (s[x][y] == '<') y--;
else y++;
if (x <= 0 || x > 2 || y <= 0 || y > n) continue;
dfs(x, y);
}
}
signed main() {
int T;
cin >> T;
while (T--) {
cin >> n;
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= n; j++)
cin >> s[i][j], v[i][j] = false;
dfs(1, 1);
if (v[2][n]) cout << "YES\n";
else cout << "NO\n";
}
}
D
倒着枚举最长长度 \(d\),\(O(n)\) 扫一遍看一看是否有合法的一段长度为 \(d\) 的串满足条件即可。
时间复杂度为 \(O(n^2)\)。
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main() {
int T;
cin >> T;
while (T--) {
string s;
cin >> s;
int n = s.size();
s = ' ' + s;
for (int i = n - n % 2; i > 0; i -= 2) {
int mx = 0, now = 0;
for (int l = 1, r = i / 2 + 1; r <= n; l++, r++)
if (s[l] == s[r] || s[l] == '?' || s[r] == '?') now++;
else mx = max(mx, now), now = 0;
mx = max(mx, now);
if (mx >= i / 2) {
cout << i << '\n';
n = -1;
break;
}
}
if (~n)
cout << "0\n";
}
return 0;
}
本文来自博客园,作者:yhbqwq,转载请注明原文链接:https://www.cnblogs.com/yhbqwq/p/18141774,谢谢QwQ

浙公网安备 33010602011771号