前言

如果有问题欢迎大家评论或私信指出


题解


A.TD

输出即可

#include<bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;

void solve() {
    double a, b;
    std::cin >> a >> b;
    std::cout << std::fixed << std::setprecision(10) << a / b;
} 

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.你好,这里是牛客竞赛

只有题里给定的四种字符串有输出结果,其余的均输出

#include<bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;

std::map<std::string, std::string> mp;

void solve() {
    std::string t;
    std::cin >> t;
    std::string s = "";
    for (int i = 0; i < t.size(); i++) {
        s += t[i];
        if (i >= 2 && t[i] == 'm' && t[i - 1] == 'o' && t[i - 2] == 'c') {
            break;
        }
    }
    // std::cout << s << '\n';
    if (mp.count(s)) {
        std::cout << mp[s] << '\n';
    }
    else {
        std::cout << "No" << '\n';
    }
} 

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

    mp["https://ac.nowcoder.com"] = "Ac";
    mp["https://www.nowcoder.com"] = "Nowcoder";
    mp["www.nowcoder.com"] = "Nowcoder";
    mp["ac.nowcoder.com"] = "Ac";
    i64 t = 1; 
    std::cin >> t;
    while (t--) {
        solve();
    }
}

C.逆序数

给定的是个排列,那我们能得到什么信息,那当然是每个数都一样,任意两个数,肯定会正着形成逆序对,或者反着形成逆序对,比如我们看数字无论怎么排列,要么的前面要么的前面,如果正着没有形成逆序对,那反着一定会是逆序对,相对的,如果这两个数正着形成了逆序对,那反着一定不形成逆序对,所以答案就是,即任选两个数会有多少种情况,减去正着形成逆序对的情况就是反着形成逆序对的情况

#include<bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;

void solve() {
    i64 n, k;
    std::cin >> n >> k;
    std::cout << (n - 1) * n / 2 - k << '\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.构造mex

让我写成屎山了,大家了解一下思路自己写吧,特判了几种情况,即我代码中写的几种情况,这里要特殊注意一种样例,好像应该有一大部分人会卡到这,比如这种,是可以构造出来的,其余的就没什么好说的了,要构造,那我们就把都先放到构造的数组里,随后把跳过去,放到数组里那个剩下的总和,其余的填即可,这里要注意,如果,剩下的那个总和就是要特殊处理比如我们肯定会先构造出来此时剩下的总和为,但也为,此时只能再填一个数,那就只能是,就无解,但如果是 ,我们肯定会先构造出来此时剩下的总和为,但有两位可以填,那就可以构造,我的大致思路是这样的,大家也可以选择其他的构造方式。

#include<bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;

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

    if (k == 0) {
        if (s < n) {
            std::cout << "NO" << '\n';
        }
        else {
            std::cout << "YES" << '\n';
            for (int i = 1; i < n; i++) {
                std::cout << 1 << ' ';
            }
            std::cout << s - (n - 1) << '\n';
        }
        return;
    }
    if (k == 1 && s == 1) {
        std::cout << "NO" << '\n';
        return;
    }
    if (k >= n) {
        if (k == n && s == (k - 1) * k / 2) {
            std::cout << "YES" << '\n';
            for (int i = 0; i < n; i++) {
                std::cout << i << ' ';
            }
            std::cout << '\n';
            return;
        }
        std::cout << "NO" << '\n';
        return;
    }

    int res = s - (k - 1) * k / 2;
    // std::cout << res << '\n';
    if (res < 0) {
        std::cout << "NO" << '\n';
        return;
    }

    else {
        if (res == k) {
            if (n - k > 1) {
                std::cout << "YES" << '\n';
                for (int i = 0; i < k; i++) {
                    std::cout << i << ' ';
                }
                std::cout << k - 1 << ' ' << 1 << ' ';
                for (int i = k + 3; i <= n; i++) {
                    std::cout << 0 << ' ';
                }
                std::cout << '\n';
            }
            else {
                std::cout << "NO" << '\n';
            }
        }
        else {
            std::cout << "YES" << '\n';
            for (int i = 0; i < k; i++) {
                std::cout << i << ' ';
            }
            std::cout << res << ' ';
            for (int i = k + 2; i <= n; i++) {
                std::cout << 0 << ' ';
            }
            std::cout << '\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.小红的X型矩阵

又写成屎山了,我们发现左斜和右斜的线可以用的坐标表示出来,比如这样的\主对角线上所有的点的横纵坐标差值都为0,那我们就可以记这条线为打上一个标记,然后我们记录每一条左右对角线上有多少个,这样的话就可以枚举每一个的中心点来算选了当前点为中心时,需要把多少变成,把多少变成,取最小值即可,但为奇偶数时候有不同哦,奇数要考虑中心点的去重问题,偶数要考虑,这是个怎么样的 比如时以下矩阵是一个合法的

1 0 0 1

0 1 1 0

0 1 1 0

1 0 0 1

#include<bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;

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

    int sum = 0;
    std::unordered_map<int, int> l, r;
    std::vector<std::vector<int> > mp(n + 1, std::vector<int> (n + 1));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            std::cin >> mp[i][j];
            if (mp[i][j] == 1) {
                sum++;
                if (i - j < 0) {
                    l[n + i - j]++;
                }
                else {
                    l[i - j]++;
                }
                r[(i + j) % n]++;
            }
        }
    }   

    auto cal1 = [&] (int x) ->int {
        return 2 * n - 1 - x + sum - x;
    };
    auto cal2 = [&] (int x) ->int {
        return 2 * n - x + sum - x;
    };

    int ans = 1e7;
    if (n & 1) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (mp[i][j] == 1) {
                    if (i - j < 0) {
                        ans = std::min(ans, cal1(l[n + i - j] + r[(i + j) % n] - 1));
                    }
                    else {
                        ans = std::min(ans, cal1(l[i - j] + r[(i + j) % n] - 1));
                    }
                }
                else {
                    if (i - j < 0) {
                        ans = std::min(ans, cal1(l[n + i - j] + r[(i + j) % n]));
                    }
                    else {
                        ans = std::min(ans, cal1(l[i - j] + r[(i + j) % n]));
                    }
                }
            }
        }
    }
    else {
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < n; j++) {
                if (mp[i][j] == 1) {
                    if (i - j < 0) {
                        ans = std::min(ans, cal2(l[n + i - j] + r[(i + 1 + j) % n]));
                    }
                    else {
                        ans = std::min(ans, cal2(l[i - j] + r[(i + 1 + j) % n]));
                    }
                }
                else {
                    if (i - j < 0) {
                        ans = std::min(ans, cal2(l[n + i - j] + r[(i + 1 + j) % n]));
                    }
                    else {
                        ans = std::min(ans, cal2(l[i - j] + r[(i + 1 + j) % n]));
                    }
                }
            }
        }
    }

    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();
    }
}

F.小红的数组回文值

我们肯定会去想过求这样一个式子,去枚举两个不相等的数让他们作为某个序列的对称位置,这样他们俩才会产生贡献,那他们俩中间的数就是可选可不选的,所以代表的就是这个意思,剩下的就是枚举这两个数的两边的数字个数一定相同,那我们开始枚举到中小的那个,在他们两边的数字个数中去取个,最后优化一下第三维,可以用范德蒙恒等式,大家可以去网上查查,再看看推论,可以优化到,就可以了

#include<bits/stdc++.h>

using i64 = long long;
using u64 = unsigned 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;

const int mod = 1e9 + 7;

int ksm (i64 a, i64 b) {
    i64 res = 1;
    while(b) {
        if (b & 1) {
            res = res * a % mod;
        }

        b >>= 1;
        a = a * a % mod;
    }

    return res;
}

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

    // std::cout << ksm(2, 30) << '\n';
    Z ans = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            if (a[i] != a[j]) {
                int l = i - 1, r = n - j;
                ans += ksm(2, j - i - 1) * comb.binom(l + r, std::min(l, r));
            }
        }
    }

    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();
    }
}