Educational Codeforces Round 105 (Rated for Div. 2)题解

CodeForces题目链接

A.ABC String

很简单的一道题目,判断YES的条件大致有三个:正反括号个数相同,第一个和最后一个字母不能是同一个,遍历时”)”的数量要保持不大于”(“。

AC Coding:

#include "bits/stdc++.h"

using namespace std;

int main(void) {
    
    
    int t;
    cin >> t;
    while (t--) {
    
    
        string str;
        cin >> str;
        int _type[3] = {
    
    0};
        int num[3] = {
    
    0};
        struct type_st {
    
    
            char a, b, c;
        }type;
        type.a = str.front() - 'A';
        type.b = str.back() - 'A';
        if (type.a == type.b) {
    
    
            cout << "NO" << endl;
            continue;
        }
        _type[type.a] = 1;
        _type[type.b] = 2;
        int another_type;
        for (int i = 0; i < 3; ++i) {
    
    
            if (_type[i] == 0) {
    
    
                type.c = i;
            }
        }
        for (auto it : str) {
    
    
            num[it - 'A']++;
        }
        if (num[type.a] + num[type.c] == num[type.b]) {
    
    
            _type[type.c] = 1;
        }else if (num[type.b] + num[type.c] == num[type.a]) {
    
    
            _type[type.c] = 2;
        }else {
    
    
            cout << "NO" << endl;
            continue;
        }
        int sum[3] = {
    
    0};
        bool isCorrect = true;
        for (auto it : str) {
    
    
            int ttype = _type[it - 'A'];
            sum[ttype]++;
            if (sum[2] > sum[1]) {
    
    
                isCorrect = false;
                break;
            }
        }
        if (isCorrect) {
    
    
            cout << "YES" << endl;
        }else {
    
    
            cout << "NO" << endl;
        }
    }

    return 0;
}

B.Berland Crossword

这题也是属于思维题, 直接暴力四个边角块的是否为黑色的所有情况并且判断是否满足边块减去两个角块是否还在0-n-2的范围内。

#include "bits/stdc++.h"

using namespace std;

int main(void) {
    
    
    int t;
    cin >> t;
    while (t--) {
    
    
        int n, u, r, d, l;
        cin >> n >> u >> r >> d >> l;
        bool isCorrect = false;
        for (int ut = 0; ut < 2; ++ut) {
    
    
            for (int rt = 0; rt < 2; ++rt) {
    
    
                for (int dt = 0; dt < 2; ++dt) {
    
    
                    for (int lt = 0; lt < 2; ++lt) {
    
    
                        if (ut + rt > u || n - 2 < u - ut - rt) {
    
    
                            continue;
                        }
                        if (rt + dt > r || n - 2 < r - rt - dt) {
    
    
                            continue;
                        }
                        if (dt + lt > d || n - 2 < d - dt - lt) {
    
    
                            continue;
                        }
                        if (lt + ut > l || n - 2 < l - lt - ut) {
    
    
                            continue;
                        }
                        isCorrect = true;
                        break;
                    }
                }
            }
        }
        if (isCorrect) {
    
    
            cout << "YES" << endl;
        }else {
    
    
            cout << "NO" << endl;
        }

    }

    return 0;
}

C.1D Sokoban

看到这个数据量就猜测是O(n)。就是一个一维的推箱子, 人物出现在零点,也就是正负要分成两部分考虑。思路是开个数组记录满足条件的箱子个数,再考虑将箱子推到每一个点时满足条件的个数并取出最大值。本来考虑到会不会用到二进制查找,看了Tutorial发现用不用都能过, 这样最后也就是O(n+m)问题不大。

#include "bits/stdc++.h"

using namespace std;

const int MAXSIZE = 2 * 1e5 + 5;

int num[MAXSIZE];

int calc(vector<int> &a, vector<int> &b) {
    
    
    int n = a.size();
    int m = b.size();
    memset(num, 0, sizeof(num));
    int r = m - 1;
    for (int i = n - 1; i >= 0; --i) {
    
    
        num[i] = num[i + 1];
        while (r >= 0 && b[r] > a[i]) {
    
    
            r--;
        }
        if (r >= 0 && b[r] == a[i]) {
    
    
            num[i]++;
        }
    }
    int ans = 0;
    int k = 0, j = 0;
    for (int i = 0; i < m; ++i) {
    
    
        while (j < n && a[j] <= b[i] + j) ++j;

        while (k < m && b[k] < b[i] + j) ++k;

        ans = max(ans, k - i + num[j]);
    }
    return ans;
}

int main(void) {
    
    
    int t;
    cin >> t;
    while (t--) {
    
    
        int n, m;
        vector<int>al, bl, ar, br;
        int temp;
        cin >> n >> m;
        for (int i = 0; i < n; ++i) {
    
    
            scanf("%d", &temp);
            if (temp < 0) al.push_back(-temp);
            else ar.push_back(temp);
        }
        for (int i = 0; i < m; ++i) {
    
    
            scanf("%d", &temp);
            if (temp < 0) bl.push_back(-temp);
            else br.push_back(temp);
        }
        reverse(al.begin(), al.end());
        reverse(bl.begin(), bl.end());
        cout << calc(al, bl) + calc(ar, br) << endl;
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/dh888222/article/details/114443483