牛客小白月赛63 (部分题解)

题目链接

A 子序列的权值最小值

注意到二进制按位与是单调不增的,所以答案为数组中所有数的按位与

#include <bits/stdc++.h>
using namespace std;

#define int long long

signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    int n;
    std::cin >> n;

    int res = (1ll << 32) - 1;
    for (int i = 0; i < n; i ++) {
        int x;
        std::cin >> x;
        res &= x;
    }

    std::cout << res << "\n";
    return 0;    
}


B 魔导师晨拥

模拟即可

#include <bits/stdc++.h>
using namespace std;

#define int long long

signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    int n,m;
    std::cin >> n >> m;

    std::vector<int> a(n);
    for (int i = 0; i < n; i ++) {
        std::cin >> a[i];
    }
    
    int d = 2,sum = 0;

    for (int i = 0; i < m; i ++) {
        for (int j = 0; j < n; j ++) {
            a[j] -= d;
            if (!a[j]) d++;
        }
        sum += d;
    }
    std::cout << sum << "\n";
    return 0;    
}



C GCPC总决赛

全排列即可。

#include <bits/stdc++.h>
using namespace std;

#define int long long

signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    int n;
    std::cin >> n;

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

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

    for (int i = 1; i <= n; i ++) {
        std::cin >> b[i];
    }

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

    iota(p.begin(), p.end(),0);
    int su = 0,fa = 0,dr = 0;

    do{
        int A = 0,B = 0;

        for (int i = 1; i <= n; i ++) {
            A += (a[p[i]] > b[i]);
            B += (a[p[i]] < b[i]);
        }
        su += A > B;
        fa += A < B;
        dr += A == B;
    }while(next_permutation(p.begin() + 1, p.end()));

    std::cout << su << " " << fa << " " << dr << "\n";
    return 0;    
}


D Ginger的大花环

贪心
考虑只使用最小花费颜色与次小花费颜色。
• 若 n mod 3 = 0,只需要分 3 个为一组,每组顺序为: 最小-最小-次小。
• 若 n mod 3 = 1,先分 3 个为一组,最后使用次小花费。
• 若 n mod 3 = 2,先分 3 个为一组,最后使用最小化费与次小花费。

#include <bits/stdc++.h>
using namespace std;

#define int long long

signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    int n,k;
    std::cin >> n >> k;

    std::vector<int> a(k);
    for (int i = 0; i < k; i ++) {
        std::cin >> a[i];
    }

    if (k == 1) {
        std::cout << "Ginger666\n";
        return 0;
    }
    sort(a.begin(), a.end());

    int f = a[0],s = a[1];

    if (n % 3 == 0) {
        cout << (n / 3) * (2 * f + s) << "\n";
    } else if (n % 3 == 1) {
        cout << (n / 3) * (2 * f + s) + s << "\n";
    } else if (n % 3 == 2) {
        cout << (n / 3) * (2 * f + s) + f + s << "\n";
    }
    return 0;    
}


E 最值区间计数

#include <bits/stdc++.h>
using namespace std;

const int P = 998244353;
using i64 = long long;
// assume -P <= x < 2P
int norm(int x) {
    if (x < 0) {
        x += P;
    }
    if (x >= P) {
        x -= P;
    }
    return x;
}
template<class T>
T power(T a, i64 b) {
    T res = 1;
    for (; b; b /= 2, a *= a) {
        if (b % 2) {
            res *= a;
        }
    }
    return res;
}
struct Z {
    int x;
    Z(int x = 0) : x(norm(x)) {}
    Z(i64 x) : x(norm(x % P)) {}
    int val() const {
        return x;
    }
    Z operator-() const {
        return Z(norm(P - x));
    }
    Z inv() const {
        assert(x != 0);
        return power(*this, P - 2);
    }
    Z &operator*=(const Z &rhs) {
        x = i64(x) * rhs.x % P;
        return *this;
    }
    Z &operator+=(const Z &rhs) {
        x = norm(x + rhs.x);
        return *this;
    }
    Z &operator-=(const Z &rhs) {
        x = norm(x - rhs.x);
        return *this;
    }
    Z &operator/=(const Z &rhs) {
        return *this *= rhs.inv();
    }
    friend Z operator*(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res *= rhs;
        return res;
    }
    friend Z operator+(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res += rhs;
        return res;
    }
    friend Z operator-(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res -= rhs;
        return res;
    }
    friend Z operator/(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res /= rhs;
        return res;
    }
    friend std::istream &operator>>(std::istream &is, Z &a) {
        i64 v;
        is >> v;
        a = Z(v);
        return is;
    }
    friend std::ostream &operator<<(std::ostream &os, const Z &a) {
        return os << a.val();
    }
};
//a^b%p
template<class T>
T qmi(T a, int b,T p) {
    T res = 1 % p;
    while (b)
    {
        if (b & 1) res = (i64)res * a % p;
        a = a * (i64)a % p;
        b >>= 1;
    }
    return res;
}

const int N = 2e6 + 10;

Z fact[N],infact[N];

void init(int n)
{
    fact[0] = infact[0] = 1;
    for(int i = 1; i < N; i ++ )
    {
       fact[i] = fact[i - 1] * i;
    }
}

signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    init(N - 10);

    int n;
    std::cin >> n;

    if (n == 1) {
        std::cout << "1\n";
        return 0;
    }

    std::cout << fact[n + 2] / 12 << "\n";
    return 0;    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值