前言

四题场,wida哥致敬传奇周赛1,如果有问题欢迎大家评论或私信指出


题解


A.Letter Song ~ 致十年后的我们

把年份加10即可,大家可以按照自己的方式,我是用字符串读入,把年份转成了整型再去给这个数字加10。

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    std::string s;
    std::cin >> s;
    int ans = 0;
    for (int i = 0; i < 4; i++) {
        ans = ans * 10 + (s[i] - '0');
    }

    std::cout << ans + 10;
    for (int i = 4; i < s.size(); i++) {
        std::cout << s[i];
    }
}  

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.简单图形问题 - 0123

根据三角形和正方形的面积计算公式,我们发现如果边长为整数,那这个三角形的面积不可能是整数,所以只需要判断是否是正方形就好了

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    int n;
    std::cin >> n;
    int a = sqrt(n);
    if (a * a == n) {
        std::cout << 0 << '\n';
    }
    else {
        std::cout << 3 << '\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.小红的机器人构造 - Ⅰ+Ⅱ+Ⅲ

又是经典写屎的一天,给大家说说我的思路,然后代码仅供参考,建议自己写一下,由于题目说的是最终目的地在)所以,我输出的方案就是把多余的步骤都删掉,让他直接走到目的地,没有回头路,就比如要走到,那我就只保留对答案有贡献那三个字符,然后方案数的话,输出的方案是最短的字符串,我们先考虑把原字符串变为改串有多少种方式,就比如原字符串种有,最简方案中只有,那么的贡献就是,即在原来的中任选两个保留下来,然后我们去考虑左右移动不会影响上下移动,说明是独立分开的,那我们就分开考虑,从最短的开始加,比如最简方案中有,我们可以再加一对不会产生影响,那把左右的方案数再加上一个组合数,就好了,上下同理,每次都拿一对一对的去加,这样才不会影响最终位置,这个说的有点乱,大家靠代码再理解一下,我简单写了点注释或者直接问我,b站牛客竞赛也会有讲题人的视频讲解。

#include<bits/stdc++.h>

using i64 = long long;

template<class T>
constexpr T power(T a, i64 b) {
    T res = 1;
    for (; b; b /= 2, a *= a) {
        if (b % 2) {
            res *= a;
        }
    }
    return res;
}

constexpr i64 mul(i64 a, i64 b, i64 p) {
    i64 res = a * b - i64(1.L * a * b / p) * p;
    res %= p;
    if (res < 0) {
        res += p;
    }
    return res;
}

template<int P>
struct MInt {
    int x;
    constexpr MInt() : x{} {}
    constexpr MInt(i64 x) : x{norm(x % getMod())} {}
    
    static int Mod;
    constexpr static int getMod() {
        if (P > 0) {
            return P;
        } else {
            return Mod;
        }
    }
    constexpr static void setMod(int Mod_) {
        Mod = Mod_;
    }
    constexpr int norm(int x) const {
        if (x < 0) {
            x += getMod();
        }
        if (x >= getMod()) {
            x -= getMod();
        }
        return x;
    }
    constexpr int val() const {
        return x;
    }
    explicit constexpr operator int() const {
        return x;
    }
    constexpr MInt operator-() const {
        MInt res;
        res.x = norm(getMod() - x);
        return res;
    }
    constexpr MInt inv() const {
        assert(x != 0);
        return power(*this, getMod() - 2);
    }
    constexpr MInt &operator*=(MInt rhs) & {
        x = 1LL * x * rhs.x % getMod();
        return *this;
    }
    constexpr MInt &operator+=(MInt rhs) & {
        x = norm(x + rhs.x);
        return *this;
    }
    constexpr MInt &operator-=(MInt rhs) & {
        x = norm(x - rhs.x);
        return *this;
    }
    constexpr MInt &operator/=(MInt rhs) & {
        return *this *= rhs.inv();
    }
    friend constexpr MInt operator*(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res *= rhs;
        return res;
    }
    friend constexpr MInt operator+(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res += rhs;
        return res;
    }
    friend constexpr MInt operator-(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res -= rhs;
        return res;
    }
    friend constexpr MInt operator/(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res /= rhs;
        return res;
    }
    friend constexpr std::istream &operator>>(std::istream &is, MInt &a) {
        i64 v;
        is >> v;
        a = MInt(v);
        return is;
    }
    friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a) {
        return os << a.val();
    }
    friend constexpr bool operator==(MInt lhs, MInt rhs) {
        return lhs.val() == rhs.val();
    }
    friend constexpr bool operator!=(MInt lhs, MInt rhs) {
        return lhs.val() != rhs.val();
    }
};

template<>
int MInt<0>::Mod = 998244353;

template<int V, int P>
constexpr MInt<P> CInv = MInt<P>(V).inv();

constexpr int P = 1000000007;
using Z = MInt<P>;

struct Comb {
    int n;
    std::vector<Z> _fac;
    std::vector<Z> _invfac;
    std::vector<Z> _inv;
    
    Comb() : n{0}, _fac{1}, _invfac{1}, _inv{0} {}
    Comb(int n) : Comb() {
        init(n);
    }
    
    void init(int m) {
        m = std::min(m, Z::getMod() - 1);
        if (m <= n) return;
        _fac.resize(m + 1);
        _invfac.resize(m + 1);
        _inv.resize(m + 1);
        
        for (int i = n + 1; i <= m; i++) {
            _fac[i] = _fac[i - 1] * i;
        }
        _invfac[m] = _fac[m].inv();
        for (int i = m; i > n; i--) {
            _invfac[i - 1] = _invfac[i] * i;
            _inv[i] = _invfac[i] * _fac[i - 1];
        }
        n = m;
    }
    
    Z fac(int m) {
        if (m > n) init(2 * m);
        return _fac[m];
    }
    Z invfac(int m) {
        if (m > n) init(2 * m);
        return _invfac[m];
    }
    Z inv(int m) {
        if (m > n) init(2 * m);
        return _inv[m];
    }
    Z binom(int n, int m) {
        if (n < m || m < 0) return 0;
        return fac(n) * invfac(m) * invfac(n - m);
    }
} comb;

void solve() {
    int n, x, y;
    std::cin >> n >> x >> y;
    std::string s;
    std::cin >> s;
    s = ' ' + s;

    i64 cntl = 0, cntr = 0, cntu = 0, cntd = 0;
    for (int i = 1; i <= n; i++) {
        if (s[i] == 'L') {
            cntl++;
        }
        else if (s[i] == 'R') {
            cntr++;
        }
        else if (s[i] == 'U') {
            cntu++;
        }
        else {
            cntd++;
        }
    }

    if (x > 0) {
        if (cntu < x) {
            std::cout << "NO" << '\n';
            return;
        }
        if (y > 0) {
            if (cntr < y) {
                std::cout << "NO" << '\n';
                return;
            }
        }
        else {
            if (cntl < -y) {
                std::cout << "NO" << '\n';
                return;
            }
        }
    }
    else {
        if (cntd < -x) {
            std::cout << "NO" << '\n';
            return;
        }
        if (y > 0) {
            if (cntr < y) {
                std::cout << "NO" << '\n';
                return;
            }
        }
        else {
            if (cntl < -y) {
                std::cout << "NO" << '\n';
                return;
            }
        }
    }
    std::cout << "YES" << ' ';
    i64 resl = cntl, resr = cntr, resu = cntu, resd = cntd;
    int x1 = x, y1 = y;
    for (int i = 1; i <= n; i++) {
        if (s[i] == 'U') {
            if (x1 > 0) {
                x1 -= 1;
                cntu -= 1;
                std::cout << s[i];
            }
        }
        else if (s[i] == 'D') {
            if (x1 < 0) {
                x1 += 1;
                cntd -= 1;
                std::cout << s[i];
            }
        }
        else if (s[i] == 'R') {
            if (y1 > 0) {
                y1 -= 1;
                cntr -= 1;
                std::cout << s[i];
            }
        }
        else {
            if (y1 < 0) {
                y1 += 1;
                cntl -= 1;
                std::cout << s[i];
            }
        }
    }
    // std::cout << cntl << ' ' << cntr << ' ' << cntu << ' ' << cntd << '\n';
    std::cout << ' ';
    Z ans = 0, ans1 = 0, ans2 = 0;
    // ans += comb.binom(resl, cntl) * comb.binom(resr, cntr) * comb.binom(resu, cntu) * comb.binom(resd, cntd);
    
    ans1 += comb.binom(resl, cntl) * comb.binom(resr, cntr);//res是每个操作的总个数
    ans2 += comb.binom(resu, cntu) * comb.binom(resd, cntd);//cnt是每个操作要删掉几个。

    cntl = resl - cntl, cntr = resr - cntr, cntu = resu - cntu, cntd = resd - cntd;//到这里cnt变成了每个操作要保留多少个
    for (int i = 1; cntl + i <= resl && cntr + i <= resr; i++) {
        ans1 += comb.binom(resl, cntl + i) * comb.binom(resr, cntr + i);
    }

    for (int i = 1; cntu + i <= resu && cntd + i <= resd; i++) {
        ans2 += comb.binom(resu, cntu + i) * comb.binom(resd, cntd + i);
    }
    // std::cout << ans1 << ' ' << ans2 << '\n';
    ans *= ans1 + ans2;
    // ans *= ans1 * ans2;
    // ans += cntl * cntr + cntu * cntd + cntl * cntr * cntu * cntd;
    std::cout << ans1 * ans2<< '\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.小红的差值构造 - easy+hard+extreme

这个属于是数学方法硬推了,我不会证明答案的正确性,首先我们发现,如果目标区间的长度大于数组长度了,肯定是把区间的一端放在中位数上。否则的话,就是把目标区间的尽可能的去围绕着的中位数,就比如的中位数是,目标区间长度是,那我目标区间的就是。如果目标区间长度是,那我的目标区间的就是可以算出来,剩下的就全是等差数列求和,大家手玩一下就能发现等差数列的规律,如果出现了这样的数列,分奇偶就能看成两个等差数列了,数列长度也可以直接计算,代码仅供参考。

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    int n, k;
    std::cin >> n >> k;
    if (k >= n) {
        i64 n1 = (n + 1) / 2, n2 = n / 2;
        std::cout << (n + 1) / 2 << ' ' << (n + 1) / 2 + k << ' ' << (n1 - 1) * n1 / 2 + (1 + n2) * n2 / 2 << '\n';
        return;
    }
    int pos = (n + 1) / 2;
    i64 l = pos - k / 2, r = pos + (k + 1) / 2;
    i64 ans = 0;
    ans += l * (l - 1) / 2;
    ans += (n - r) * (n - r + 1) / 2;
    i64 n1 = (k + 2) / 2, n2 = (k + 1) / 2;
    ans += (n1 - 1) * n1 / 2 + (n2 - 1) * n2 / 2;
    // std::cout << n1 << ' ' << n2 << '\n';
    std::cout << l << ' ' << r << ' ' << 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();
    }
}