Educational Codeforces Round 105 (Rated for Div. 2)


Educational Codeforces Round 105 (Rated for Div. 2)

A - ABC String

第一個字母只能是 '(', 最后一個字母不等於第一個字母且只能是 ')'

所以就剩下一個字母沒確定, 直接分情況討論兩邊即可

int a[3], x[2], y[2];
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        string s; cin >> s; bool f = 1, g = 1;
        memset(a, -1, sizeof a); rep (i, 0, 1) x[i] = y[i] = 0; 
        if (s[0] == s.back()) { cout << "NO\n"; continue; }
        a[s[0] - 'A'] = 0; a[s.back() - 'A'] = 1;
        for (auto &i : s) {
            if (a[i - 'A'] != -1) ++x[a[i - 'A']], ++y[a[i - 'A']];
            else ++x[0], ++y[1];
            if (x[0] < x[1]) f = 0;
            if (y[0] < y[1]) g = 0;
        }
        if (f && x[0] == x[1]) cout << "YES\n";
        else if (g && y[0] == y[1]) cout << "YES\n";
        else cout << "NO\n";
    }
    return 0;
}

B - Berland Crossword

狀壓枚舉四個角有沒有黑塊

int a[5], b[5];
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n; rep (i, 1, 4) cin >> a[i]; bool f = 0;
        rep (i, 0, (1 << 4) - 1) {
            rep (i, 1, 4) b[i] = a[i];
            if (i & 1) --b[1], --b[4];
            if (i >> 1 & 1) --b[1], --b[2];
            if (i >> 2 & 1) --b[2], --b[3];
            if (i >> 3 & 1) --b[3], --b[4];
            bool g = 1;
            rep (i, 1, 4) if (b[i] < 0 || b[i] > n - 2) g = 0;
            f = f || g;
        }
        cout << (f ? "YES\n" : "NO\n");
    }
    return 0;
}

C - 1D Sokoban

直接正負對稱, 直接把負數 reverse, 在取反, 就是兩次相同的過程

然后就是模擬推箱子取max即可

ll a[N], b[N];
 
int work(int x, int y, int n, int m) {
    int ans = 0, res = 0; unordered_set<ll> st;
    rep (i, y, m) st.insert(b[i]);
    rep (i, x, n) if (st.count(a[i])) ++res; ans = res;
    for (int i = x, j = y, k = y; i <= n && j <= m; ++i) {
        if (st.count(a[i])) --res;
        while (j <= m && b[j] <= a[i]) ++j;
        for (; j <= m && ((i < n && b[j] < a[i + 1]) || i == n); ++j) {
            while (b[j] - b[k] > i - x) ++k;
            umax(ans, res + min(j - k + 1, i - x + 1));
        }
    }
    return ans;
}
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n >> m; int x = n + 1, y = m + 1; a[0] = b[0] = -1;
        rep (i, 1, n) { cin >> a[i]; if (a[i - 1] * a[i] < 0) x = i; }
        rep (i, 1, m) { cin >> b[i]; if (b[i - 1] * b[i] < 0) y = i; }
        reverse(a + 1, a + x); reverse(b + 1, b + y);
        rep (i, 1, x - 1) a[i] = -a[i];
        rep (i, 1, y - 1) b[i] = -b[i];
        cout << work(x, y, n, m) + work(1, 1, x - 1, y - 1) << '\n';
    }
    return 0;
}

D - Dogeforces

好氣, 沒輸出總經理, 最后沒時間改了, 艹, B卡太長時間了, 各種枚舉情況, 直接狀壓枚舉不就好了.... 暴力都不會

貪心, 為了防止有的經理沒有兩個下屬, 盡量多添加經理, 比如 a[i][j] = a[x][y] = c, 直接 i,j 從屬 e, x,y 從屬 e,

而不是 i,j,x,y 從屬於一個經理, 導致最后 i,j,x,y的上上級只有 i,j,x,y 的上級 這一個下屬

從低到高枚舉工資, 並查集添加經理即可, 還是模擬, 最壞情況就是每兩個員工有個經理, 成線段樹的空間棵 N * 4

vector<PII> h[N * 10];
int b[N << 2], f[N << 4], a[N << 4], fa[N << 4];
 
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
 
int main() {
    IOS; cin >> n; k = n; int mx = 0;
    rep(i, 1, n) f[i] = i;
    rep(i, 1, n) rep(j, 1, n) {
        cin >> m;
        if (i == j) b[i] = m;
        else if (i < j) h[m].pb(i, j), umax(mx, m);
    }
    rep(i, 1, mx - 1) {
        if (h[i].empty()) continue;
        int cur = k;
        for (auto& j : h[i]) fa[j.fi] = find(j.fi), fa[j.se] = find(j.se);
        for (auto& j : h[i]) f[find(fa[j.fi])] = find(fa[j.se]);
        for (auto& j : h[i]) {
            int x = find(j.fi);
            if (x <= cur) b[++k] = i, f[x] = f[k] = k, x = k;
            a[fa[j.fi]] = a[fa[j.se]] = x;
        }
    } b[++k] = mx;
    for (auto& i : h[mx]) a[find(i.fi)] = a[find(i.se)] = k;
    cout << k << '\n';
    rep(i, 1, k) cout << b[i] << ' '; cout << '\n';
    cout << k << '\n';
    rep(i, 1, k - 1) cout << i << ' ' << a[i] << '\n';
    return 0;
}

E - A-Z Graph

忘了和哪一次了, 差不多, 讓你選奇數和偶數的回文對稱路徑,

這道比那道還簡單, 為偶數有兩個點存在邊且字符相同 yes, 為奇數, 兩個點互相有邊即可

unordered_map<int, char> h[N];

int main() {
    IOS; cin >> n >> m; int x = 0, y = 0;
    rep (i, 1, m) {
        char op; cin >> op;
        if (op == '+') {
            int u, v; char c; cin >> u >> v >> c;
            h[u][v] = c;
            auto it = h[v].find(u);
            if (it != h[v].end() && it->se == c) ++x;
            if (it != h[v].end()) ++y;
        } else if (op == '-') {
            int u, v; cin >> u >> v;
            auto aa = h[u].find(v), it = h[v].find(u);
            if (it != h[v].end() && it->se == aa->se) --x;
            if (it != h[v].end()) --y;
            h[u].erase(aa);
        } else {
            int k; cin >> k;
            if (k & 1) cout << (y ? "YES\n" : "NO\n");
            else cout << (x ? "YES\n" : "NO\n");
        }
    }
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM