Codeforces Round 885 (Div. 2)

这些文章涉及Vika解决的编程题目,涵盖递归、优化算法、利用模运算简化计算以及数学问题如整数分解和动态规划,展示了在解决实际问题中的技术运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. Vika and Her Friends

 只需要判断奇偶即可, 核心代码

void solve() {
    int n, m, k;
    cin >> n >> m >> k;
    int x, y;
    cin >> x >> y;
    int d = (x + y) % 2;
    int f = 0;
    for (int i = 1; i <= k; i ++) {
        cin >> x >> y;
        if ((x + y) % 2 == d) f = 1;
    }
    if (!f) cout << "YES" << endl;
    else cout << "NO" << endl;
}

B. Vika and the Bridge

 记一下相邻相同数字的最长距离和次长距离, 最优操作可以将最长距离减半,核心代码

void solve() {
    int n, k; cin >> n >> k;
    vector<int> d(k + 1), cnt(k + 1), d2(k + 1);
    vector<int> pre(k + 1);
    for (int i = 1; i <= n; i ++) {
        int x; cin >> x;
        int dd = i - pre[x] - 1;
        if (dd > d[x])  d2[x] = d[x], d[x] = dd;
        else if (dd > d2[x]) d2[x] = dd;
        pre[x] = i;
    }
    for (int i = 1; i <= k; i ++) {
        int dd = n - pre[i];
        // if (i == 1) debug(dd)
        if (d[i] < dd) d2[i] = d[i], d[i] = dd;
        else if (d2[i] < dd) d2[i] = dd;;
    }
    // for (int i = 1; i <= k; i ++) cout << d2[i] << " ";
    //     cout <<" sdsd" << endl;
    int ans = INF;
    for (int i = 1; i <= k; i ++) {
        int dd = max(d[i] / 2, d2[i]);
        ans = min(ans, dd);
    }
    cout << ans << endl;
}

C. Vika and Price Tags

 相减的操作循环可以全部除去gcd,之后的操作是奇偶循环,判断一下所有周期模三是否相等即可

void solve() {
    int n; cin >> n;
    vector<int> a(n), b(n), d(n);
    for (int i = 0; i < n; i ++) cin >> a[i];
    for (int i = 0; i < n; i ++) cin >> b[i];
    for (int i = 0; i < n; i ++) {
        int gc = gcd(a[i], b[i]);
        if (gc != 0) {
            a[i] /= gc, b[i] /= gc;
        }
        if (a[i] == 0 && b[i] == 0) continue;
        if (a[i] % 2 == 0) d[i] = 1;
        else if (b[i] % 2 == 0) d[i] = 2;
        else d[i] = 4;
    }
    int s = 0;
    for (int i = 0; i < n; i ++) {
        s |= d[i];
    }
    if (s == 0 || s == 1 || s == 2 || s == 4) cout << "YES" << endl;
    else cout << "NO" << endl;
}

D. Vika and Bonuses

 只加最后一位会进入循环,特判一下0,5即可,之后是二次函数求最值

void solve() {
    int s, k;
    cin >> s >> k;
    function<int(int, int)> f = [&](int s, int k) -> int {
        if (k == 0) return 0;
        int ans = s * k;
        if (s % 10 == 0) {
            return ans;
        }
        if (s % 10 != 2) {
            ans = max(ans, f(s + s % 10, k - 1));
        } else {
            // 进入2 4 8 6的循环
            int h[5] = {0, 2, 6, 14, 20};
            auto g = [&](int n) {
                return (s + n / 4 * 20 + h[n % 4]) * (k - n);
            };
            int m = max((5 * k - s) / 10, 0ll);
            for (int i = max(m - 100, 0ll); i <= min(m + 100, k); i ++) {
                ans = max(ans, g(i));
            }
        }
        return ans;
    };
    cout << f(s, k) << endl;
}

E. Vika and Stone Skipping

题意:一个可爱的小女孩lin喜欢打水漂,她打出的水漂每次在水面上飞行的距离成一个等差数列且公差为1,她有一个幸运数字x,她希望计算有多少种等差数列能经过坐标x

题目还给了一个小质数M,处理的时候特别判断一下

void solve() {
    int xx, q, M;
    map<int, int> mp;
    cin >> xx >> q >> M;
    xx /= lowbit(xx);
    for (int i = 2; i * i <= xx; i ++) {
        if (xx % i == 0) {
            int cnt = 0;
            while (xx % i == 0) {
                cnt ++;
                xx /= i;
            }
            mp[i] = cnt;
        }
    }
    if (xx > 1) mp[xx] = 1;
    vector<ll> inv(N);
    inv[1] = 1;
    for (int i = 2; i < N && i < M; i ++) {
        inv[i] = M - inv[M % i] * (M / i) % M;
    }
    ll ans = 1;
    int cntM = 0;
    auto get_M = [&](int x) {
        while (x % M == 0) {
            cntM ++;
            x /= M;
        }
        ans *= x % M;
        ans %= M;
    };
    auto get_x = [&](int x) {
        while (x % M == 0) {
            cntM --;
            x /= M;
        }
        ans *= inv[x % M];
        ans %= M;
    };
    for (auto [x, y] : mp) {
        get_M(y + 1);
    }
    for (int i = 1; i <= q; i ++) {
        int x; cin >> x;
        x /= lowbit(x);
        while (x != 1) {
            int p = pr[x], cnt = 0;
            while (x % p == 0) {
                x /= p;
                cnt ++;
            }
            get_x(mp[p] + 1);
            mp[p] += cnt;
            get_M(mp[p] + 1);
        }
        if (cntM > 0) cout << 0 << endl;
        else cout << ans << endl;
    }
}

F. Vika and Wiki

 手玩一下发现一定可以实现,且操作之后会进入周期

void solve() {
    int n; cin >> n;
    vector<int> a(n);
    int ans = 0;
    for (auto &x : a) cin >> x;
    for (int i = n / 2; i >= 1; i /= 2) {
        vector<int> b(n);
        for (int j = 0; j < n; j ++) {
            b[j] = a[j] ^ a[(j + i) % n];
        }
        int cnt = 0;
        for (int j = 0; j < n; j ++) cnt += b[j] == 0;
        if (cnt != n) {
            a = b;
            ans += i;
        }
    }
    int cnt = 0;
    for (int i = 0; i < n; i ++) cnt += a[i] == 0;
    ans += cnt != n;
    cout << ans << endl;
}
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值