Codeforces Round #691 (Div. 2)

Codeforces Round #691 (Div. 2)

A - Red-Blue Shuffle

int main() {
    IOS;
    for (cin >> _; _; --_) {
        string a, b; cin >> n >> a >> b;
        int cnt = 0;
        rep (i, 0, n - 1) cnt += a[i] > b[i] ? 1 : a[i] < b[i] ? -1 : 0;
        if (cnt > 0) cout << "RED
";
        else if (cnt == 0) cout << "EQUAL
";
        else cout << "BLUE
";
    }
    return 0;
}

B - Move and Turn

找规律, 暴力打个表, 你会发现

对于分开奇偶之后都是个等差数列, 当然你愿意去找规律也可

能打表的为啥要动脑呢,老懒狗了

int main() {
    IOS; cin >> n;
    if (n & 1) cout << ((ll)(1 + (n + 1 >> 1)) * (n + 1 >> 1) << 1);
    else cout << ((n >> 1) * 3 + 1 + (ll)(n >> 1) * (n - 2 >> 1));
    return 0;
}

啥打表代码?

int d[4][2] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }, a[2] = { 1, 3 };
 
int main() {
    IOS; 
    for (cin >> _; _; --_) {
        n = _;
        queue<pair<PII, PII>> q;
        rep (i, 0, 3) q.push({ { 0, 0 }, { 0, i } });
        int g = 1;
        while (1) {
            if (q.front().se.fi == n) break;
            auto cur = q.front(); q.pop(); ++cur.se.fi;
            rep (i, 0, 1) {
                int nd = (cur.se.se + a[i]) % 4;
                q.push({ { cur.fi.fi + d[nd][0], cur.fi.se + d[nd][1] }, { cur.se.fi, nd } });
            }
        }
        set<PII> ans;
        while (!q.empty()) ans.insert({ q.front().fi.fi, q.front().fi.se }), q.pop();
        cout << ans.size() << ' ';
    }
    return 0;
}

C - Row GCD

好, 很快啊, 啪的一下把我秒了,

辗转相除不仅适用于两个数 gcd(x, y) = gcd(x, y - x),

它适用于多个数 (gcd(a_1 + b_j, a_2 + b_j, ..., a_n + b_j) = gcd(a_1 + b_j, a_2 + b_j, ..., a_n + b_j - a_{n - 1} - b_j))

最后 (gcd(a_1 + b_j, a_2 + b_j, ..., a_n + b_j) = gcd(a_1 + b_j, a_2 - a_1, ..., a_n - a_{n - 1}))

先预处理 (gcd(a_2 - a_1, ..., a_n - a_{n - 1})), 最后O(n)对每个(a_1 + b_j) 算gcd即可

int main() {
    IOS; cin >> n >> m >> a[1];
    rep (i, 2, n) cin >> a[i], c[i] = __gcd(c[i - 1], a[i] - a[i - 1]);
    rep (i, 1, m) cin >> b[i], cout << abs(__gcd(a[1] + b[i], c[n])) << ' ';
    return 0;
}

D - Glass Half Spilled

假设选中的k个杯子总的容量为A, 总的容水量为B, 则对于k答案就是 B + min(A - B, ((sum_{b_i}) - B) / 2.0)

所以有了 f[i][k][A] = B, 在前i个杯子里选k个杯子使得总容量为A的容水量最大为f[i][k][A], 在滚动数组省掉一维空间 f[k][A]

则对于 k, 答案为 max(f[k][A] + min(A - f[k][A], (sumb - f[k][A]) / 2.0))

double ans[N];
int a[N], b[N], f[N][N * N];

int main() {
    IOS; cin >> n;
    rep (i, 1, n) cin >> a[i] >> b[i], b[0] += b[i], a[0] += a[i];
    memset(f, -1, sizeof f); f[0][0] = 0;
    rep (i, 1, n) per (k, i, 1) per (j, a[0], a[i])
        if (f[k - 1][j - a[i]] != -1) umax(f[k][j], f[k - 1][j - a[i]] + b[i]);
    rep (i, 1, n) rep (j, 0, a[0]) if (f[i][j] != -1)
        umax(ans[i], f[i][j] + min(j - f[i][j] + 0.0, (b[0] - f[i][j]) / 2.0));
    rep (i, 1, n) cout << setiosflags(ios::fixed) << setprecision(9) << ans[i] << ' ';
    return 0;
}
原文地址:https://www.cnblogs.com/2aptx4869/p/14167267.html