Codeforces Round 1016 (Div. 3)

注: G 暂时不会

A

题目大意

一个正整数\(k\),如果对于任意不小于\(k\)的数\(n\),都能写出长度为\(k\)且总和为n的回文数组,则输出YES,否则输出NO

解题思路

  • \(k\)是奇数,输出YES
  • \(k\)是偶数,输出NO

代码实现

#include<bits/stdc++.h>

void Main() {
    int n;
    std::cin >> n;
    if (n & 1) {
        std::cout << "YES" << '\n';
    } else {
        std::cout << "NO" << '\n';
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0), std::cout.tie(0);
    int T = 1;
    std::cin >> T;
    while (T--) {
        Main();
    }
    return 0;
}

B

题目大意

一个正整数\(n\),各个数位之和为\(m\),它的代价为\(n\div m\)
为了使代价减小,可以删除某些数位,但是最后不能为\(0\)
输出代价最小时,删除数字的最小数量。

解题思路

  • \(n\)很大,需要高精度。
  • 分子和分母都为正整数,所以最小代价就是\(1\),只剩下一个数字。
  • 找到不是\(0\)的最低数位,删掉高位的非零数和低位的\(0\)

代码实现

#include<bits/stdc++.h>

void Main() {
    std::string s;
    std::cin >> s;
    int n = s.size();
    for (int i = n - 1; i >= 0; i--) {
        if (s[i] != '0') {
            std::cout << n - 1 - count(s.begin(), s.begin() + i, '0') << '\n';
            return;
        }
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0), std::cout.tie(0);
    int T = 1;
    std::cin >> T;
    while (T--) {
        Main();
    }
    return 0;
}

C

题目大意

正整数\(x,k\)\(y\)\(x\)的十进制重复\(k\)次,如果\(y\)是质数,输出YES,否则输出NO

解题思路

  • \(x=1,k=1\)时,输出NO
  • \(x\geq 2,k\geq 2\)时,\(y=x\times (p^{k-1}+p^{k-2}+\cdots+p^{1}+p^{0})\)\(p\)是比\(x\)大的最小的10的次幂。
    所以\(y\)一定有因子\(x\),输出NO
  • 其他情况,暴力判断因子。
  • 时间复杂度\(O(t\times \sqrt{x})\)

代码实现

#include<bits/stdc++.h>

void Main() {
    int x, k;
    std::cin >> x >> k;
    if (x >= 2 && k >= 2) {
        std::cout << "NO" << '\n';
        return;
    }
    if (x == 1) {
        if (k == 1) {
            std::cout << "NO" << '\n';
            return;
        }
        int y = 0;
        for (int i = 0; i < k; i++) {
            y = y * 10 + 1;
        }
        for (int i = 2; i * i <= y; i++) {
            if (y % i == 0) {
                std::cout << "NO" << '\n';
                return;
            }
        }
        std::cout << "YES" << '\n';
        return;
    }
    for (int i = 2; i * i <= x; i++) {
        if (x % i == 0) {
            std::cout << "NO" << '\n';
            return;
        }
    }
    std::cout << "YES" << '\n';
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0), std::cout.tie(0);
    int T = 1;
    std::cin >> T;
    while (T--) {
        Main();
    }
    return 0;
}

D

解题思路

  • 递归分治
  • 标准的板子题,就是代码不太好写。

代码实现

#include<bits/stdc++.h>

using i64 = long long;

i64 find(i64 i, int lx, int ly, int rx, int ry, int a, int b) {
    if (lx == a && ly == b) {
        return i;
    }
    int midx = lx + rx >> 1, midy = ly + ry >> 1;
    i64 sum = (1LL * midx - lx + 1) * (1LL * midy - ly + 1);
    if (a <= midx && b <= midy) {
        return find(i, lx, ly, midx, midy, a, b);
    }
    if (a <= midx && b > midy) {
        return find(i + 3 * sum, lx, midy + 1, midx, ry, a, b);
    }
    if (a > midx && b <= midy) {
        return find(i + 2 * sum, midx + 1, ly, rx, midy, a, b);
    }
    return find(i + sum, midx + 1, midy + 1, rx, ry, a, b);
}

std::pair<int, int> get(i64 d, i64 l, i64 r, int lx, int ly, int rx, int ry) {
    if (lx == rx && ly == ry) {
        return {lx, ly};
    }
    i64 k = (r - l + 1) >> 2;
    int midx = lx + rx >> 1, midy = ly + ry >> 1;
    if (d < l + k) {
        return get(d, l, l + k - 1, lx, ly, midx, midy);
    }
    if (d < l + 2 * k) {
        return get(d, l + k, l + 2 * k - 1, midx + 1, midy + 1, rx, ry);
    }
    if (d < l + 3 * k) {
        return get(d, l + 2 * k, l + 3 * k - 1, midx + 1, ly, rx, midy);
    }
    return get(d, l + 3 * k, r, lx, midy + 1, midx, ry);
}

void Main() {
    int n, q;
    std::cin >> n >> q;
    while (q--) {
        std::string op;
        int x, y;
        i64 d;
        std::cin >> op;
        if (op == "->") {
            std::cin >> x >> y;
            std::cout << find(1, 1, 1, 1 << n, 1 << n, x, y) << '\n';
        } else {
            std::cin >> d;
            auto [dx, dy] = get(d, 1, (1LL << n) * (1LL << n), 1, 1, (1 << n), (1 << n));
            std::cout << dx << " " << dy << '\n';
        }
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0), std::cout.tie(0);
    int T = 1;
    std::cin >> T;
    while (T--) {
        Main();
    }
    return 0;
}

E

题目大意

一个长度为\(n\)的数组\(a\),将数组划分成\(k\)段子数组,代价\(x\)为每段\(mex\)中的最小值。
划分时使\(x\)尽可能大,输出\(x\)的最大值。

解题思路

  • 二分答案
  • check时,遇到\(mex\geq x\)就重新开一段,判断能否划分成\(k\)段及以上。

代码实现

#include<bits/stdc++.h>

void Main() {
    int n, k;
    std::cin >> n >> k;
    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }
    int l = 0, r = n;

    auto check = [&] (int x) -> bool {
        int cnt = 0, mex = 0;
        std::vector<bool> mp(x);
        for (int i = 0; i < n; i++) {
            if (a[i] < x) {
                mp[a[i]] = 1;
            }
            while (mp[mex]) {
                mex++;
            }
            if (mex >= x) {
                mex = 0;
                cnt++;
                fill(mp.begin(), mp.end(), 0);
            }
        }
        return cnt >= k;
    };

    while (l < r) {
        int mid = l + r + 1 >> 1;
        if (check(mid)) {
            l = mid;
        } else {
            r = mid - 1;
        }
    }
    std::cout << l << '\n';
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0), std::cout.tie(0);
    int T = 1;
    std::cin >> T;
    while (T--) {
        Main();
    }
    return 0;
}

F

解题思路

  • 模拟
  • chose存下神经网络\(i\)可以处理的位置\(j\),sol存下可以处理第\(j\)位的神经网络\(i\)
  • 每次选择处理数量最多的神经网络\(pos\),然后把其他神经网络上\(pos\)处理过的位置删掉,这样就可以在下一次直接加\(2\times size\)(操作2变空白,再操作1放上合法的)。

好像做麻烦了,看到很多佬直接\(3\times n-2\times ans\)

代码实现

#include<bits/stdc++.h>

void Main() {
    int n, m;
    std::cin >> n >> m;
    std::vector<std::string> a(n);
    std::vector b(m, std::vector<std::string>(n));
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }
    std::vector<std::set<int>> chose(m);
    std::vector<std::vector<int>> sol(n);
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            std::cin >> b[i][j];
            if (b[i][j] == a[j]) {
                chose[i].insert(j);
                sol[j].push_back(i);
            }
        }
    }
    int ans = 0;
    for (int s = 0; s < n; ) {
        int pos = 0;
        for (int i = 0; i < m; i++) {
            if (chose[i].size() > chose[pos].size()) {
                pos = i;
            }
        }
        if (chose[pos].empty()) {
            std::cout << -1 << '\n';
            return;
        }
        if (!ans) {
            ans = n;
            s += chose[pos].size();
        } else {
            ans += 2 * chose[pos].size();
            s += chose[pos].size();
        }
        for (auto i : chose[pos]) {
            for (auto j : sol[i]) {
                if (j != pos) {
                    chose[j].erase(i);
                }
            }
        }
        chose[pos].clear();
    }
    std::cout << ans << '\n';
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0), std::cout.tie(0);
    int T = 1;
    std::cin >> T;
    while (T--) {
        Main();
    }
    return 0;
}
posted @ 2025-04-09 09:29  sunjiànqiáng  阅读(136)  评论(0)    收藏  举报