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;
}
posted @ 2024-04-17 21:00  yhbqwq  阅读(23)  评论(0)    收藏  举报