1. 程式人生 > 其它 >Educational Codeforces Round 4 覆盤

Educational Codeforces Round 4 覆盤

A

讀完題總是會楞一下,然後才開始寫。

一遍 AC。

const int MAXN = 100 + 10;
 
int n, p, q;
char ss[MAXN];
 
int main() {
    scanf("%d %d %d", &n, &p, &q);
    scanf("%s", ss);
    for (int ps = 0; ps <= n; ++ps) {
        if ((n - ps * p) < 0) break;
        if ((n - ps * p) % q) continue;
        int qs = (n - ps * p) / q;
        printf("%d", ps + qs);
        for (int i = 0; i < ps * p; ++i) {
            if (i % p == 0) puts("");
            putchar(ss[i]);
        }
        for (int i = ps * p; i < n; ++i) {
            if ((i - ps * p) % q == 0) puts("");
            putchar(ss[i]);
        }
        return 0;
    }
    puts("-1");
    return 0;
}

B

讀題就讀了好幾分鐘。讀懂了就很好寫了。

一遍 AC。

const int MAXN = 2e5 + 10;
 
int pos[MAXN];
int n;
 
int main() {
    n = read();
    rep (i, 1, n) pos[read()] = i;
    lli ans = 0;
    rep (i, 1, n - 1) ans += std::abs(pos[i] - pos[i + 1]);
    printf("%lld\n", ans);
    return 0;
}

C

第一發忘了判斷棧是否為空,然後 WA on 10

const int MAXN = 1e6 + 10;
 
int n;
char ss[MAXN];
 
std::stack<char> stk;
 
int main() {
    scanf("%s", ss + 1);
    int ans = 0;
    n = (int) strlen(ss + 1);
    rep (i, 1, n) {
        if (ss[i] == '<' || ss[i] == '{' || ss[i] == '[' || ss[i] == '(') {
            stk.push(ss[i]);
        } else {
            if (stk.empty()) {
                puts("Impossible");
                return 0;
            }
            switch (ss[i]) {
            case '>':
                ans += (stk.top() != '<');
                break;
            case '}':
                ans += (stk.top() != '{');
                break;
            case ']':
                ans += (stk.top() != '[');
                break;
            case ')':
                ans += (stk.top() != '(');
                break;
            }
            stk.pop();
        }
    }
    if (stk.empty()) printf("%d\n", ans);
    else puts("Impossible");
    return 0;
}

D. The Union of k-Segments

類似於之前 ABC 某題的思路,先離散化,然後差分,統計答案的時候用原陣列的值。

但是這麼做只能處理整數端點,對於 \([1, 2] + [3, 4]\) 這種是沒法處理的,所以考慮把端點都 \(\times 2\),然後在離散化數組裡加入 \(2l - 1, 2l, 2r, 2r + 1\) 四個值,這樣就能很方便處理了。

然後調了一場沒調出來,賽後才發現自己訪問原陣列的時候腦抽了,std::vector 從 0 開始儲存結果少減了一個 1.

#易錯警示:分清 0-indexed 和 1-indexed 的區別。

const int MAXN = 1e6 + 10;
 
int n, k;
int tl[MAXN], tr[MAXN];
 
std::vector<int> lisan;
 
int diff[MAXN << 2];
 
int main() {
    n = read(); k = read();
    rep (i, 1, n) {
        int u = read(); int v = read();
        tl[i] = u, tr[i] = v;
        lisan.push_back(u * 2 - 1);
        lisan.push_back(u * 2);
        lisan.push_back(v * 2);
        lisan.push_back(v * 2 + 1);
    }
    std::sort(ALL(lisan));
    auto it = std::unique(ALL(lisan));
    if (it != lisan.end()) lisan.erase(it, lisan.end());
 
    rep (i, 1, n) {
        int fl = (int) (std::lower_bound(ALL(lisan), tl[i] * 2) - lisan.begin() + 1);
        int fr = (int) (std::lower_bound(ALL(lisan), tr[i] * 2) - lisan.begin() + 1);
        // DEBUG(fl); DEBUG(fr);
        ++diff[fl]; --diff[fr + 1];
 
    }
 
    rep (i, 1, (int) lisan.size() + 1) diff[i] += diff[i - 1];
 
    // rep (i, 1, (int) lisan.size() + 1) printf("%d ", diff[i]);
 
    int tl = 0;
    std::vector<std::pair<int, int> > anss;
    lisan.push_back(0);
    rep (i, 1, (int) lisan.size() - 1) {
        if (diff[i] < k) {
            if (tl) {
                anss.push_back({lisan[tl - 1] / 2, (lisan[i - 2]) / 2});
                tl = 0;
            }
        } else {
            if (!tl) tl = i;
        }
    }
    printf("%d\n", (int) anss.size());
    for (auto v : anss) {
        printf("%d %d\n", v.fi, v.se);
    }
    return 0;
}

或者有更簡單的做法,你甚至不需要一個完整的 diff 陣列,只需要把左端點看成一個 +1 的事件,右端點看成一個 -1 的事件,然後排個序按上面的過程掃一遍就可以了。

const int MAXN = 1e6 + 10;
 
int n, k;
struct Seg { int l, x; }; std::vector<Seg> events;
bool operator < (const Seg &x, const Seg &y) { return x.l == y.l ? x.x > y.x : x.l < y.l; }
 
int main() {
    n = read(); k = read();
    rep (i, 1, n) {
        int l = read(); int r = read();
        events.push_back({l * 2 - 1, 0});
        events.push_back({l * 2, 1});
        events.push_back({r * 2 + 1, -1});
    } std::sort(ALL(events));
    std::vector<std::pair<int, int> > ans;
    int cnt = 0;
    int tl = -(1 << 30);
    for (auto e : events) {
        cnt += e.x;
        if (cnt >= k) {
            if (tl == -(1 << 30)) tl = e.l;
        } else {
            if (tl != -(1 << 30)) {
                ans.push_back({tl, e.l - 1});
                tl = -(1 << 30);
            }
        }
    }
    printf("%d\n", (int) ans.size());
    for (auto v : ans) printf("%d %d\n", v.fi / 2, v.se / 2);
    return 0;
}