zoukankan      html  css  js  c++  java
  • Codeforces Global Round 12

    A - Avoid Trygub

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            string s; cin >> n >> s;
            sort(all(s)); cout << s << '
    ';
        }
        return 0;
    }
    

    B - Balls of Steel

    枚举找就完事

    PII a[N];
     
    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n >> k;
            rep (i, 1, n) cin >> a[i].fi >> a[i].se;
            int ans = -1;
            rep (i, 1, n) {
                bool f = 0;
                rep (j, 1, n) if (abs(a[i].fi - a[j].fi) + abs(a[i].se - a[j].se) > k) { f = 1; break; }
                if (!f) { ans = 1; break; }
            }
            cout << ans << '
    ';
        }
        return 0;
    }
    

    C1 & C2 - Errich-Tac-Toe

    明显是考虑(i + j) % 3, 记 ++cnt[(i + j) % 3][s[i][j] == 'X']

    最后无非选择 i, j(-1<i,j<3, i!=j) 使得 s[i][1] + s[j][0] <= k/3, 即使得每3个相邻的标记中存在两个不同的标记

    一定存在这样的 i, j使得 <= k/3, 自己画个表就明白了

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n; memset(c, 0, sizeof c);
            rep (i, 0, n - 1) {
                cin >> s[i];
                rep (j, 0, n - 1) if (s[i][j] != '.') ++c[(i + j) % 3][s[i][j] == 'X'], ++k;
            }
            rep (i, 0, 2) rep (j, 0, 2) if (i != j && c[i][1] + c[j][0] <= k / 3) {
                rep (x, 0, n - 1) rep (y, 0, n - 1) if (s[x][y] != '.')
                    if ((x + y) % 3 == i) s[x][y] = 'O';
                    else if ((x + y) % 3 == j) s[x][y] = 'X';
                k = 0;
            }
            rep (i, 0, n - 1) cout << s[i] << '
    ';
        }
        return 0;
    }
    

    D - Rating Compression

    md, 向获取 a[i] 能被选出来的范围 l~r, 用了线段树+倍增 t7

    直接单调栈不好吗? 不过cf (nlog^2n) 常数稍大点竟然过不去, 离谱

    nt a[N], b[N], l[N];
     
    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n;
            rep(i, 1, n) cin >> a[i], b[i] = 0;
            stack<PII> q;
            rep(i, 1, n) {
                while (!q.empty() && q.top().fi >= a[i]) umax(b[q.top().fi], i - l[q.top().se]), q.pop();
                if (q.empty()) l[i] = 1;
                else l[i] = q.top().se + 1;
                q.push({ a[i], i });
            }
            while (!q.empty()) umax(b[q.top().fi], n + 1 - l[q.top().se]), q.pop();
            rep(i, 2, n) umin(b[i], b[i - 1]);
            rep(i, 1, n) cout << (b[n - i + 1] >= i); cout << '
    ';
        }
        return 0;
    }
    

    E - Capitalism

    建图跑个多源最短路就好,

    b = 1, d[u][v] = 1, d[v][u] = -1;

    b = 0, d[u][v] = d[v][u] = 1;

    分别跑出来以 i 为最少的资本, 的最短路

    找到以谁为起点s, 差值最大就行

    判 no, 就对于 d[s][u] == d[s][v] 为 no 就行

    顺便用 d[i][i] 判个负环

    int d[N][N];
    
    int main() {
        IOS; cin >> n >> m; vector<pair<PII, int>> e(m);
        rep (i, 1, n) rep (j, 1, n) d[i][j] = i == j ? 0 : inf;
        for (auto &i : e) {
            cin >> i.fi.fi >> i.fi.se >> i.se;
            d[i.fi.fi][i.fi.se] = 1;
            d[i.fi.se][i.fi.fi] = i.se ? -1 : 1;
        }
        rep (k, 1, n) rep (i, 1, n) rep (j, 1, n) umin(d[i][j], d[i][k] + d[k][j]);
        int mx = -1, w;
        rep (i, 1, n) {
            if (d[i][i] < 0) { cout << "NO"; return 0; }
            for (auto &j : e) if (d[i][j.fi.fi] == d[i][j.fi.se]) { cout << "NO"; return 0; }
            rep (j, 1, n) if (d[i][j] > mx) mx = d[i][j], w = i; 
        }
        cout << "YES
    " << mx << '
    ';
        rep (i, 1, n) cout << d[w][i] << ' ';
        return 0;
    }
    

    F - The Struggling Contestant

    先把-1考虑了, 无非是某个数多余 (n + 1) / 2

    然后是将序列分段, 记录每个数作为端点必须要出现的次数

    比如 1 2 2 3 4 5, 对于2来说, a[2]于a[3]要隔开,并且这两个数要作为切割后的序列的端点(前端和后端)

    对于 1, 5, 本来就是端点, 直接+1, 最后就是端点之间的相互拼接, 不过拼接的两个端点不能是相同的数,

    你不能那端点 a[2] 和 a[3] 拼接, 但可以 a[2] 和 a[1]/a[6] 拼接, 既然都是端点了, 肯定贪心的先和其他端点拼接

    最后如果存在 没有拼接的端点, 纪要使用那些单点了,

    es 1 2 2 2 2 3 4, a[2] a[1] a[3] a[6] a[7] a[4] a[5] a[6]

    当前剩下端点 a[4] 和 a[5], 只好使用 a[6] 去分割了 2 1 2 4 2 3 2

    答案也就是 k + max(0, (max_f[x]) - k - 2), f[i] 表示 i 作为端点的数量, k是相邻端点的数量

    简单来说 k, 是必须要所示的贡献, 两个相邻的相同的数, 拆入一个数, 最少贡献 +1, 1 2 2 -> 2 1 2 贡献为1

    然后是相互插入 2 2 2 3 3 -> 2 3 2 3 2, 没贡献, 2 2 2 2 3 3 4 -> 2 3 2 3 2 4 2, 额外使用了单点 a[7], 贡献+1

    1 2 2 2 3 3 4 4 4 5 -> 1 2 3 4 2 3 4 2 4 5, 无额外贡献, 说白了就是看那个最多的数作为端点其他数能不能将这个完全分割

    为啥是 max(0, (max_f[x]) - k - 2) 要减个2? 你把那个最多的点作为整个序列的前后端点, 不挨着其他数

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n; VI a(n + 1), cnt(n + 1), f(n + 1); k = 0;
            rep (i, 1, n) {
                cin >> a[i]; ++cnt[a[i]];
                if (i > 1 && a[i] == a[i - 1]) f[a[i]] += 2, ++k;
            }
            if (*max_element(all(cnt)) > (n + 1) / 2) { cout << "-1
    "; continue; }
            ++f[a[1]], ++f[a[n]];
            cout << k + max(0, *max_element(all(f)) - k - 2) << '
    ';
        }
        return 0;
    }
    
  • 相关阅读:
    SAP库存账龄分析报表
    elasticsearch 同义词配置搜索
    elasticsearch 上下文
    git 修改源路径 修改项目地址
    intellij IDEA 无限试用
    Kubernetes 安装Redis集群
    helm安装ingress
    安装Helm
    Kubernetes Rook + Ceph
    GIT 将工作区恢复到上次提交的内容 commit your changes or stash them before you can merge Your local changes to the following files would be overwritten by merge
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14096408.html
Copyright © 2011-2022 走看看