Codeforces Round #677 (Div. 3)

A

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n; m = n; k = 0;
        while (m) ++k, m /= 10;
        cout << (n % 10 - 1) * 10  + (1 + k) * (k) / 2 << '\n'; 
    } 
    return 0;
}

B

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n; k = m = 0;
        rep (i, 1, n) {
            cin >> a[i];
            if (a[i] == 1 && a[i - 1] == 0) k += (m ? i - m - 1 : 0);
            else if (a[i] == 0 && a[i - 1] == 1) m = i - 1;
        }
        cout << k << '\n';
    } 
    return 0;
}

C

反正最后要吃最大值, 那不如直接让最大值升一级, 就可以全吃

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n; VI a(n); k = -1;
        for (auto &i : a) cin >> i;
        m = *max_element(all(a));
        rep (i, 0, n - 1) if (a[i] == m && ((i && a[i - 1] != m) || (i + 1 < n && a[i + 1] != m))) k = i + 1;
        cout << k << '\n';
    } 
    return 0;
}

D

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n; VI a(n + 1);
        vector<VI> e; vector<VI> r;
        unordered_map<int, int> st;
        rep (i, 1, n) {
            cin >> a[i];
            if (!st.count(a[i])) st[a[i]] = e.size(), e.pb(VI(1, i));
            else e[st[a[i]]].pb(i);
        }
        if (e.size() < 2) { cout << "NO\n"; continue; }
        else cout << "YES\n";
 
        rep (i, 0, e.size() - 2) for (auto j : e[i]) cout << j << ' ' << e[i + 1][0] << '\n';
        rep (i, 1, e.back().size() - 1) cout << e.back()[i] << ' ' << e[0][0] << '\n';
    } 
    return 0;
}

E

组合数学 首先是对称的, 随意选人要 / 2, \(C_n^{\frac{n}{2}} / 2\)

环内全排列, 因为循环可以重复, 所以 / n, 也就是$ sqr(A_{n/2}^{n/2} / n) = sqr(A_{n/2-1}^{n/2-1})$

然后我的 C 递推是减半的, 没除2

ll c[21][21], fac[21];
 
void init(int n) {
    c[1][1] = fac[1] = fac[0] = 1;
    rep (i, 2, n) fac[i] = fac[i - 1] * i;
    rep (i, 2, n) rep (j, 1, i) c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
}
 
int main() {
    IOS; init(20);
    cin >> n; cout << c[n][n/2] << '\n';
    cout << c[n][n / 2] * sqr(fac[n / 2 - 1]);
    return 0;
}

F

dp就完事了

int main() {
    IOS; cin >> n >> m >> k;
    memset(f, -1, sizeof f); f[1][0][0] = 0;
    rep(i, 1, n) {
        rep(j, 1, m) {
            cin >> a[i][j];
            per(p, k - 1, 0)
                per(q, min(m >> 1, j), 1) {
                if (f[j & 1][((p - a[i][j]) % k + k) % k][q - 1] > -1)
                    umax(f[j & 1 ^ 1][p][q], f[j & 1][((p - a[i][j]) % k + k) % k][q - 1] + a[i][j]);
            }
            per(p, k - 1, 0)
                per(q, min(m >> 1, j), 0) {
                    umax(f[j & 1 ^ 1][p][q], f[j & 1][p][q]);
            }
        }
 
        rep(p, 0, k - 1)
            rep(q, 1, m >> 1)
                  umax(f[1][p][0], max(f[1][p][q], f[0][p][q])), f[0][p][q] = f[1][p][q] = -1;
    }
    cout << f[1][0][0] << '\n';
    return 0;
}

G

n*nlogn, 跑迪杰斯特拉

线性去判断每条边变成0 的答案

int main() {
    IOS; cin >> n >> m >> k; vector<PII> ed;
    vector<vector<PII>> h(n + 1); vector<PII> e;
    rep (i, 1, m) {
        int u, v, c; cin >> u >> v >> c;
        e.pb({u, v}); h[u].pb({v, c}); h[v].pb({u, c});
    }
 
    rep (i, 1, k) {
        int u, v; cin >> u >> v;
        ed.pb({u, v});
    }
 
    vector<vector<ll>> d(n + 1, vector<ll>(n + 1, 1ll << 60));
    rep (s, 1, n) {
        priority_queue<PII> q; d[s][s] = 0;
        q.push({0, s});
        while (!q.empty()) {
            PII p = q.top(); q.pop();
            if (d[s][p.se] != -p.fi) continue;
            for (auto &y : h[p.se]) {
                int w = d[s][p.se] + y.se;
                if (w >= d[s][y.fi]) continue;
                d[s][y.fi] = w; q.push({ -w, y.fi});
            }
        }
    }
 
    ll ans = 1ll << 62;
    for (auto g : e) {
        ll tmp = 0;
        for (auto gg : ed) tmp += min({d[gg.fi][gg.se], d[gg.fi][g.fi] + d[g.se][gg.se], d[gg.fi][g.se] + d[g.fi][gg.se]});
        umin(ans, tmp);
    }
    cout << ans;
    return 0;
}
posted @ 2020-10-22 00:32  洛绫璃  阅读(140)  评论(0编辑  收藏  举报