Codeforces Round #692 (Div. 2, based on Technocup 2021 Elimination Round 3)

Codeforces Round #692 (Div. 2, based on Technocup 2021 Elimination Round 3)

从传智杯到牛客到cf, 一条龙, 脑子有点呆

A - In-game Chat

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n >>  s + 1;
        int c = 0;
        per (i, n, 1) if (s[i] == ')') ++c; else break;
        cout << (c * 2 > n ? "YES
" : "NO
");
    }
    return 0;
}

B - Fair Numbers

1~9的公倍数为2520, 故最多检测2519个数, 就能找到最小的公平数

bool check(ll x) {
    ll y = x;
    while (x) {
        if (x % 10 == 0) { x /= 10; continue; }
        if (y % (x % 10)) return 0;
        x /= 10;
    }
    return 1;
}
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        ll n; cin >> n;
        for (ll i = n; i <= 1e18; ++i) 
            if (check(i)) { cout << i << '
'; break; }
    }
    return 0;
}

C - Peaceful Rooks

按理来说每个数(不在对角线上的)移动一次刚刚好

但是他要就不能相互攻击, 有的就要先让出个位置了, 比如 (2, 3), (3, 4) (4, 2)

成了个环, 要先有个点到其他位置呆着所以总步数 +1

就用并查集判有多少个环就行了

int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n >> m;
        rep (i, 1, n) f[i] = i;
        ll ans = 0;
        rep (i, 1, m) {
            int x, y; cin >> x >> y;
            if (x == y) continue; ++ans;
            x = find(x), y = find(y);
            if (x == y) ++ans;
            else f[y] = x;
        }
        cout << ans << '
';
    }
    return 0;
}

D - Grime Zoo

当?序列为 111..000 or 000...111 or 00..00 or 11..11 时最小

不存在 01, 10相间, 这个证明有点费事, 就整个不能 0101的把 不能 11000011000的自己证吧

对于 ..?..?.?.?.. 问号(这四个问号在是相邻的)对应 0101, 记 st[i][0, 1, 2] 表示从1~i中有多少个 0, 1, ?, ed[i][0,1,2] 同理

0101 下标分别为 a, b, c, d 且 a < b < c < d, 序列总长为n

对于b和c贡献为 st[b][0] * x + ed[b][0] * y + st[c][1] * y + ed[c][1] * x

将序列变为 0001 bc的贡献为: (st[b][1] - 1(b变成0了-1)) * x + (ed[b][1] - 1) * y + (st[c][1] - 1) * y + (ed[c][1] - 1) * x

不论变成 0001 还是 0111 都比 0101 要小, 当然肉眼也可见,

想想也因该发现 00000, 1111最小毕竟为0, 但是我们能改的位置有限, 记我们只能改 问号为 1 or 0

抛弃不能改的位置也理应是 00000, 1111是最小, 但还要考虑 不能改的位置那只好妥协成了 00001111.. or 11111000.. or 00000.. or 111..

int main() {
    IOS; ll x, y; cin >> s >> x >> y;
    rep (i, 1, s.size()) rep (j, 0, 2)
        st[i][j] = st[i - 1][j] + (j < 2 ? s[i - 1] == '0' + j : s[i - 1] == '?');
    per (i, s.size(), 1) rep (j, 0, 2)
        ed[i][j] = ed[i + 1][j] + (j < 2 ? s[i - 1] == '0' + j : s[i - 1] == '?');
    int cnt0 = 0, cnt1 = 0;
    ll t = 0, res, ans;
    rep (i, 1, s.size())
        if (s[i - 1] == '0') ++cnt0, t += cnt1 * y;
        else ++cnt1, t += cnt0 * x;
    res = ans = t;
    rep (i, 1, s.size()) if (s[i - 1] == '?') {
        res -= (st[i - 1][0] + st[i - 1][2]) * x + ed[i + 1][0] * y;
        res += st[i - 1][1] * y + (ed[i + 1][1] + ed[i + 1][2]) * x;
        umin(ans, res);
    } res = t;
    per (i, s.size(), 1) if (s[i - 1] == '?') {
        res -= st[i - 1][0] * x + (ed[i + 1][0] + ed[i + 1][2]) * y;
        res += (st[i - 1][1] + st[i - 1][2]) * y + ed[i + 1][1] * x;
        umin(ans, res);
    }
    cout << ans;
    return 0;
}
原文地址:https://www.cnblogs.com/2aptx4869/p/14167919.html