Educational Codeforces Round 174 (Rated for Div. 2)

A. Was there an Array?

题目大意

在一个数组中,如果一个数和它相邻的两个数字都相等,那么在特征数组中它就是1,否则为0(最两侧的数字不计,特征数组长度为n-2),现在给定特征数组,问能否构造出数组满足这个特征数组

解题思路

构造不出来就是有冲突,相邻不相等可以随意构造,而相等则存在限制,显然这里可能有的冲突就是x两侧的值已经固定且和x相等,但是特征数组却显示不相等,因此只需要判断是否存在特征数组101子串即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

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

    int tt;
    std::cin >> tt;

    while (tt--) {
        int n;
        std::cin >> n;

        std::string s;
        for (int i = 0; i < n - 2; i++) {
            int x;
            std::cin >> x;
            s += '0' + x;
        }

        if (s.find("101") == -1) {
            std::cout << "YES\n";
        } else {
            std::cout << "NO\n";
        }
    }
}

B. Set of Strangers

题目大意

给你一个数字矩阵,每次可以修改所有数值为x且上下左右四个方向不相邻的数字为y,问至少修改多少次能让矩阵的数字全都一样

解题思路

让这些数字变成没出现过的新数字肯定不优,因此标记出现的数字,最后在这里找即可,可以发现同一个数字修改的次数要么是1要么是2,因此两层循环暴力搜索最后去掉一次最大操作(变成那个数字)即可即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

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

    int tt;
    std::cin >> tt;

    while (tt--) {
        int n, m;
        std::cin >> n >> m;

        std::vector<int> cnt(n * m + 1), f(n * m + 1);
        std::vector<std::vector<int>> g(n, std::vector<int>(m));
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                std::cin >> g[i][j];
                f[g[i][j]] = 1;
                cnt[g[i][j]] = 1;
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (j + 1 < m && g[i][j + 1] == g[i][j] || i + 1 < n && g[i + 1][j] == g[i][j]) {
                    cnt[g[i][j]] = 2;
                }
            }
        }

        int ans = 0, maxn = 0;
        for (int i = 1; i <= n * m; i++) {
            if (f[i]) {
                ans += cnt[i];
                maxn = std::max(maxn, cnt[i]);
            }
        }

        std::cout << ans - maxn << "\n";
    }
}

C. Beautiful Sequence

题目大意

一个数组中除了最两侧的数字,每一个数字都满足左边有一个数字比它小,右边有一个数字比它大,那么这个就是漂亮数组。现在给定一个元素只含1-3的数组,问有多少子序列是漂亮数组,对答案模998244353

解题思路

显然满足的子序列只有最左边是1最右边是3,中间全是2的。预处理出模意义下2的幂和逆元以及区间内2的数量,再对遇到1和3的时候分类处理即可,例如i处是1,j处是3,则这一部分的贡献就是 2pre[j1]pre[i]1,遇到1就要统计数量并加上需要处理的逆元,3和之前所有的1都能配上,所以要乘上累加的逆元部分,再减去前面的1的数量就是最后的答案,注意取模过程中可能出现负数

代码实现

#include <bits/stdc++.h>>

using i64 = long long;
const int MOD = 998244353;
const int N = 2e5 + 10;

i64 ksm(i64 a, i64 b) {
    i64 res = 1;
    a %= MOD;
    while (b) {
        if (b & 1) {
            res = res * a % MOD;
        }
        a = a * a % MOD;
        b >>= 1;
    }
    return res;
}

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

    std::vector<i64> pow2(N, 1), inv2(N, 1);
    for (int i = 1; i < N; i++) {
        pow2[i] = (pow2[i - 1] * 2) % MOD;
        inv2[i] = (inv2[i - 1] * ksm(2, MOD - 2)) % MOD;
    }

    int tt;
    std::cin >> tt;

    while (tt--) {
        int n;
        std::cin >> n;

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

        i64 ans = 0, sum = 0, cnt = 0;
        for (int i = 1; i <= n; i++) {
            if (a[i] == 1) {
                sum = (sum + inv2[pre[i]]) % MOD;
                cnt++;
            } else if (a[i] == 3){
                ans = (ans + ((pow2[pre[i - 1]] * sum) % MOD - cnt) % MOD + MOD) % MOD;
            }
        }

        std::cout << ans % MOD << "\n";
    }
}

D. Palindrome Shuffle

题目大意

给你一个偶数长度的字符串,你可以对它的子串进行一次重排然后把他变成回文串,问最短子串是多少

解题思路

先对两侧的回文部分进行处理,取出中间非回文的部分,再统计字母数量,由于最后是偶数长度的回文串,所以一定可以分成两半,先对字母数量减半得到构成半个回文串的字母数量,再从一侧扫描过去不断减去当前的字符,直到这一侧的数量不满足半个回文串要求的数量,除此之外还有一种特殊情况,也就是恰好平分了数量,这时还要从中间往两侧扩展一次更新一下答案,最后对左右两侧扫一遍的答案取小即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

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

    int tt;
    std::cin >> tt;

    while (tt--) {
        std::string s;
        std::cin >> s;

        int l = 0, r = s.size();
        while (r - l >= 2 && s[r - 1] == s[l]) {
            l++, r--;
        }
        s = s.substr(l, r - l);

        std::vector<int> cnt(26);
        for (auto ch : s) {
            cnt[ch - 'a']++;
        }
        for (auto& x : cnt) {
            x /= 2;
        }

        int ans = s.size();
        for (int i = 0, len = s.size(); i < 2; i++, len = s.size(), std::reverse(s.begin(), s.end())) {
            auto c = cnt;
            for (auto ch : s) {
                if (c[ch - 'a'] == 0) {
                    break;
                }
                len--;
                c[ch - 'a']--;
            }
            if (2 * len == s.size()) {
                while (len) {
                    if (s[len - 1] != s[s.size() - len]) {
                        break;
                    }
                    len--;
                }
            }
            ans = std::min(ans, len);
        }

        std::cout << ans << "\n";
    }
}
posted @   udiandianis  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
  1. 1 山海不可平 CMJ
山海不可平 - CMJ
00:00 / 00:00
An audio error has occurred.

纯音乐,请欣赏

点击右上角即可分享
微信分享提示