前言

不会F,待补,如果有问题欢迎大家评论或私信指出


题解


A.小红的好数

判断一下字符串前两位是否相等即可

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    std::string s;
    std::cin >> s;
    if (s[0] == s[1] && s.size() == 2) {
        std::cout << "Yes" << '\n';
    }
    else {
        std::cout << "No" << '\n';
    }
}  

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

    i64 t = 1; 
    // std::cin >> t;
    while (t--) {
        solve();
    }
}

B.小红的好数组

暴力判断所有长度为k的子数组是否可以修改小于等于一个位置使其变成回文串

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    int n, k;
    std::cin >> n >> k;

    std::vector<int> a(n + 1);

    auto check = [&] (int l, int r) -> bool {
        int res = 0;
        while(l <= r) {
            if (a[l] != a[r]) {
                res++;
            }
            l++, r--;
        }
        if (res == 1) {
            return true;
        }
        else {
            return false;
        }
    };

    int ans = 0;
    for (int i = 1; i <= n; i++) {
        std::cin >> a[i];
        if (i >= k) {
            if(check(i - k + 1, i)) {
                ans++;
            }
        }
    }
    std::cout << ans << '\n';
}  

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

    i64 t = 1; 
    // std::cin >> t;
    while (t--) {
        solve();
    }
}

C.小红的矩阵行走

就bfs,但需要判断一下,下一步要走的地方如果和起始位置的值相同才能继续走。

#include<bits/stdc++.h>

using i64 = long long;

int dx[2] = {0, 1};
int dy[2] = {1 ,0};

void solve() {
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<int> > mp(n + 1, std::vector<int> (m + 1));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            std::cin >> mp[i][j];
        }
    }

    std::queue<std::tuple<int, int, int> > q;
    q.push({1, 1, mp[1][1]});
    while(!q.empty()) {
        auto [x, y, v] = q.front();
        q.pop();
        if (x == n && y == m) {
            std::cout << "Yes" << '\n';
            return;
        }
        for (int i = 0; i < 2; i++) {
            int xx = x + dx[i], yy = y + dy[i];
            if (xx < 1 || xx > n || yy < 1 || yy > m) continue;
            if (mp[xx][yy] != v) {
                continue;
            }
            q.push({xx, yy, v});
        }
    }

    std::cout << "No" << '\n';
}  

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

    i64 t = 1; 
    std::cin >> t;
    while (t--) {
        solve();
    }
}

D.小红的行列式构造

不会证明,我纯手玩模拟出来的规律。

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    int x;
    std::cin >> x;
    if (x >= 0) {
        std::cout << "1 1 1\n";
        std::cout << "1 2 1\n";
        std::cout << "1 1 " << x + 1 << '\n';
    }
    else {
        std::cout << "-1 -1 -1\n";
        std::cout << "-1 -2 -1\n";
        std::cout << "-1 -1 " << x - 1 << '\n';
    }
}  

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

    i64 t = 1; 
    // std::cin >> t;
    while (t--) {
        solve();
    }
}

E.小红的 red 计数

就考虑翻转某一段区间多了什么和少了什么,考虑red时如果ed都在区间内,那翻转时就会把red变成rde,同理,会吧rde变为red,如果re在区间内,那就会把red变换成erd,会把erd变换成red,如果red都在区间内就会把red变换der,把der变换成red。算出以上贡献即可。所以答案就是-区间前r的个数和区间内ed的乘积+区间前r和区间内de的乘积 - 区间内red的个数 + 区间内der的个数 - 区间内re和区间后d的个数的乘积 + 区间内er和区间后d个数的乘积。问题变成了,区间内re的个数要怎么算呢,就是到区间右端点内re的个数-到区间左端点内re的个数-区间前r的个数乘上区间内e的个数。自己再思考一下那区间内red的个数怎么求呢。代码仅供参考,维护前缀和的时候还打了遍差分。

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    i64 n, q;
    std::cin >> n >> q;
    std::string s;
    std::cin >> s;
    s = ' ' + s;

    //r, e, d, re, er, ed, de, red, der
    std::vector<i64> prer(n + 1), pred(n + 1), pree(n + 1), prere(n + 1), preer(n + 1), preed(n + 1), prede(n + 1), prered(n + 1), preder(n + 1);
    for (i64 i = 1; i <= n; i++) {
        if (s[i] == 'r') {
            prer[i] += 1;
            preer[i] += pree[i - 1];
            preder[i] += prede[i - 1];
        }
        else if (s[i] == 'e') {
            pree[i] += 1;
            prere[i] += prer[i - 1];
            prede[i] += pred[i - 1];
        }
        else if (s[i] == 'd') {
            pred[i] += 1;
            preed[i] += pree[i - 1];
            prered[i] += prere[i - 1];
        }
        prer[i] += prer[i - 1];
        pree[i] += pree[i - 1];
        pred[i] += pred[i - 1];
        prere[i] += prere[i - 1];
        preer[i] += preer[i - 1];
        preed[i] += preed[i - 1];
        prede[i] += prede[i - 1];
        prered[i] += prered[i - 1];
        preder[i] += preder[i - 1];
    }

    auto sumr = [&](i64 l, i64 r) -> i64 {
        return prer[r] - prer[l - 1];
    };

    auto sume = [&](i64 l, i64 r) -> i64 {
        return pree[r] - pree[l - 1];
    };

    auto sumd = [&](i64 l, i64 r) -> i64 {
        return pred[r] - pred[l - 1];
    };

    auto sumre = [&](i64 l, i64 r) -> i64 {
        return prere[r] - prere[l - 1] - sumr(1, l - 1) * sume(l, r);
    };

    auto sumer = [&](i64 l, i64 r) -> i64 {
        return preer[r] - preer[l - 1] - sume(1, l - 1) * sumr(l, r);
    };

    auto sumed = [&](i64 l, i64 r) -> i64 {
        return preed[r] - preed[l - 1] - sume(1, l - 1) * sumd(l, r);
    };

    auto sumde = [&](i64 l, i64 r) -> i64 {
        return prede[r] - prede[l - 1] - sumd(1, l - 1) * sume(l, r);
    };

    auto sumred = [&](i64 l, i64 r) -> i64 {
        return prered[r] - prered[l - 1] - sumr(1, l - 1) * sumed(l, r) - sumre(1, l - 1) * sumd(l, r);
    };

    auto sumder = [&](i64 l, i64 r) -> i64 {
        return preder[r] - preder[l - 1] - sumd(1, l - 1) * sumer(l, r) - sumde(1, l - 1) * sumr(l, r);
    };

    while (q--) {
        i64 l, r;
        std::cin >> l >> r;
        i64 num = sumr(1, l - 1) * sumde(l, r) - sumr(1, l - 1) * sumed(l ,r) - sumred(l, r) + sumder(l, r) - sumre(l, r) * sumd(r + 1, n) + sumer(l, r) * sumd(r + 1, n); 
        std::cout << num + prered[n] << '\n';
    }
}

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

    i64 t = 1;
    // std::cin >> t;
    while (t--) {
        solve();
    }
}
}