ICPC 2024 武汉邀请赛

I. Cyclic Apple Strings

题目大意

给定一个01字符串,每次可以选择一个子串移动,问至少操作多少次才能最小化字符串字典序

解题思路

统计不在开头的0的段数即可,简单计算就是10子串有多少

代码实现

print(input().count("10"))

K. Party Games

题目大意

f和p在一个升序排列上进行游戏,每次可以删除最左或者最右的数字,当剩余数字异或和为0时获胜,问f先手能否必胜

解题思路

打表找规律

代码实现

for _ in range(int(input())):
    n = int(input())
    if n // 2 % 2:
        print("Pinkie Pie")
    else:
        print("Fluttershy")

B. Countless Me

题目大意

给定一个数组a,每次操作可以选择\(a_i\)\(a_j\)变为\(a_i+x\)\(a_j-x\),一共可以操作n次,最小化数组中所有元素按位与的结果

解题思路

看似只有n次,但是已经可以任意修改所有数字的值,因此只需要每次都从高位加上不小于平均数的二的幂即可

代码实现

import math
n = int(input())
a = sum(list(map(int, input().split())))
ans = 0
while a:
    t = 1
    while t * 2 <= math.ceil(a / n):
        t *= 2
    ans += t
    a -= min(a // t, n) * t
print(ans)

F. Custom-Made Clothes

题目大意

交互题,用不超过50000次询问找到矩阵第k大的元素,“? i j x”表示询问\(a_{ij}\)是否不大于x,矩阵的每个元素满足都不小于当前位置左边和上面的元素

解题思路

矩阵是一个左上小,右下大的矩阵,为了方便计算,可以转化为求n*n-k+1小的元素,由于矩阵元素有序,因此可以考虑二分目标元素,判断是否有足够数量的数字不小于目标元素

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    int n, k;
    std::cin >> n >> k;
    k = n * n - k + 1;

    auto check = [&](int x) -> bool {
        for (int i = 1, cnt = 0, j = n, f; i <= n; i++) {
            for (; j > 0; j--) {
                std::cout << "? " << i << " " << j << " " << x << std::endl;
                std::cin >> f;
                if (f) {
                    break;
                }
            }
            cnt += j;
            if (cnt >= k) {
                return false;
            }
        }
        return true;
    };

    int l = 1, r = n * n, ans = 1;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (check(mid)) {
            l = mid + 1;
        } else {
            r = mid - 1;
            ans = mid;
        }
    }

    std::cout << "! " << ans << std::endl;
}

D. ICPC

题目大意

给定一个数组,问从每一个位置出发移动1~2n次到达的数字之和的最大值,每次移动可以左移或右移一格

解题思路

显然最优的答案改变方向不会超过一次方向,对两个方向分别计算取大即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);

    int n;
    std::cin >> n;

    std::vector<i64> pre(n + 1);
    for (int i = 1; i <= n; i++) {
        int x;
        std::cin >> x;
        pre[i] = pre[i - 1] + x;
    }

    std::vector<std::vector<i64>> L(n + 2, std::vector<i64>(n * 2 + 1)), R(n + 2, std::vector<i64>(n * 2 + 1));
    for (int i = n; i >= 1; i--) {
        for (int j = 1; j <= n * 2; j++) {
            L[i][j] = std::max(L[i + 1][j - 1], pre[i] - pre[std::max(1, i - j) - 1]);
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n * 2; j++) {
            R[i][j] = std::max(R[i - 1][j - 1], pre[std::min(n, i + j)] - pre[i - 1]);
        }
    }

    i64 ans = 0;
    for (int i = 1; i <= n; i++) {
        i64 x = 0;
        for (int j = 1; j <= n * 2; j++) {
            x ^= (j * std::max(L[i][j], R[i][j]));
        }
        ans ^= (i + x);
    }

    std::cout << ans << "\n";
}
posted @ 2025-05-09 13:26  udiandianis  阅读(89)  评论(0)    收藏  举报