Featured image of post Educational Codeforces Round #183

Educational Codeforces Round #183

B

题目大意:Monocarp 有一副从 $1$ 到 $n$ 编号的牌。起初,这些牌按照从小到大的顺序排列,$1$ 在顶部,$n$ 在底部。Monocarp 对这副牌进行了 $k$ 次操作。每次操作类型有三种: - 移除顶部的牌; - 移除底部的牌; - 移除顶部或底部的任意一张牌。需要判断每张牌的状态:它现在是否仍在牌堆中,已经被移除,还是可能两种情况都有可能。

数据范围:$1 \le t \le 10^4$,$1 \le k \le n \le 2 \cdot 10^5$,$\sum n \le 2 \cdot 10^5$。

思路:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void solve() {
    ll n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    vl a(n + 1, 1);
    int tem = 0;
    int l = 1, r = n;
    rep(i, 0, k - 1) {
        if (s[i] == '0') {
            a[l] = 0;
            l++;
        } else if (s[i] == '1') {
            a[r] = 0;
            r--;
        } else
            tem++;
    }
    if (r - l + 1 <= tem) {
        rep(i, 0, n - 1) cout << '-';
        cout << endl;
        return ;
    }
    rep(i, l, l + tem - 1) {
        if (a[i] == 0)
            continue;
        else
            a[i] = 2;
    }
    frep(i, r, r - tem + 1) {
        if (a[i] == 0)
            continue;
        else
            a[i] = 2;
    }
    rep(i, 1, n) {
        if (a[i] == 0)
            cout << '-';
        else if (a[i] == 1)
            cout << '+';
        else
            cout << '?';
    }
    cout << endl;
    return;
}

C

题目大意:Monocarp 有一个长度为 $n$ 的字符串 $s$,只包含字母 ‘a’ 和 ‘b’。他想从字符串 $s$ 中删除一些(可能为零)连续的字母,使得剩余字符串中 ‘a’ 和 ‘b’ 的个数相等。Monocarp 可以从字符串 $s$ 的任意位置开始删除连续的字母。Monocarp 非常喜欢他的字符串 $s$,因此他希望删除的连续字母数量尽可能少。需要确定,Monocarp 需要从字符串 $s$ 中删除的连续字母的最小数量,使得剩余字符串中 ‘a’ 和 ‘b’ 的数量相等。

数据范围:$1 \le t \le 10^4$,$2 \le n \le 2 \times 10^5$,$\sum n \le 2 \times 10^5$。

思路:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void solve() {
    ll n;
    cin >> n;
    string s;
    cin >> s;
    int tot0 = 0, tot1 = 0;
    rep(i, 0, n - 1) {
        if (s[i] == 'a')
            tot0++;
        else
            tot1++;
    }
    map<ll, ll> ma;
    ma[0] = -1;
    ll tem = tot0 - tot1;
    if (tem == 0) {
        cout << 0 << endl;
        return;
    }
    ll tem2 = 0;
    ll ans = LLONG_MAX;
    rep(i, 0, n - 1) {
        tem2 += (s[i] == 'a' ? 1 : -1);
        if (ma.find(tem2 - tem) != ma.end()) ans = min(ans, i - ma[tem2 - tem]);
        ma[tem2] = i;
    }
    cout << (ans == n ? -1 : ans) << endl;
    return;
}