zoukankan      html  css  js  c++  java
  • 「赛后总结」Codeforces Round #680 (Div. 2)

    题目/题解

    A. Array Rearrangment

    题意:

    给定两个序列 (a,b) 和一个数 (x),判断能否对 (b) 进行排序使得 (forall i in[1,n])(a_i+b_i le x)

    题解:

    (a) 升序排列,(b) 降序排列。

    (m_a)(a) 中最小的,(m_b)(b) 中最大的,如果 (p+m_ble x) 并且 (m_a + q le x)(m_ale p)(q le m_b)),那么 (m_a+m_ble x)(p+qle x)。可知不会变差。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #define M 51
    
    int t, n, m, a[M], b[M];
    
    bool cmp(int x, int y) {
        return x > y;
    }
    
    int main() {
        scanf("%d", &t);
        while (t--) {
            scanf("%d %d", &n, &m); bool flag = true;
            for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
            for (int i = 1; i <= n; ++i) scanf("%d", &b[i]);
            std::sort(a + 1, a + n + 1), std::sort(b + 1, b + n + 1, cmp);
            for (int i = 1; i <= n; ++i) {
                if (a[i] + b[i] > m) {
                    flag = false;
                    puts("No");
                    break;
                }
            }
            if (flag) puts("Yes");
        }
        return 0;
    }
    

    B. Elimination

    题意:

    两场比赛,排名按分数降序。知道第一场比赛的第一百名选手第一场得分为 (a),并且前一百名选手第二场比赛的得分不低于 (b)。知道第二场比赛的第一百名选手第二场比赛的得分为 (c),并且前一百名选手第一场比赛的得分不低于 (d)。求总分第一百名分最少是多少。

    题解:

    已知有一百人总分不低于 (a+b),一百人总分不低于 (c+d),所以总分第一百名分最少为 (max(a+b,c+d))

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    
    int min(int a, int b) { return a < b ? a : b; }
    int max(int a, int b) { return a > b ? a : b; }
    
    int t, a, b, c, d;
    
    int main() {
        std::cin >> t;
        while (t--) {
            std::cin >> a >> b >> c >> d;
            std::cout << max(a + b, c + d) << '
    ';
        }
        return 0;
    }
    

    C. Division

    题意:

    多测,给定 (p,q),求出一个最大的 (x) 使得 (xmid p) 并且 (q mid x)

    (1 leq p leq 10^{18})(1 leq q leq 10^9)

    题解:

    对于 (p < q) 的情况答案是 (p)

    对于 (p ge q) 的情况,如果 (q mid p) 答案是 (p)

    如果 (q mid p),对 (p,q) 分解质因数。

    (p = {p_1}_{a_1} imes {p_2}^{a_2} imes dots imes {p_k} ^{a_k})

    (q = {p_1}_{b_1} imes {p_2}^{b_2} imes dots imes {p_k} ^{b_k})

    因为 (q mid p) 所以 (forall i in[1,k])(a_ige b_i),目的就是找一个最小的除数 (d) 使得 (dfrac{p}{d})(对 (d) 分解质因数指数记为 (c))不再满足 (forall i in[1,k])(a_ige b_i - c_i)

    最小的 (d) 可以在对 (q) 分解质因数的过程中求出。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    
    typedef long long ll;
    inline void read(ll &T) {
        ll x = 0;
        bool f = 0;
        char c = getchar();
        while (c < '0' || c > '9') {
            if (c == '-') f = !f;
            c = getchar();
        }
        while (c >= '0' && c <= '9') {
            x = x * 10 + c - '0';
            c = getchar();
        }
        T = f ? -x : x;
    }
    
    int t;
    ll p, q;
    
    ll qpow(int a, int b) {
        ll ans = 1, base = a;
        while (b) {
            if (b & 1) ans = base * ans;
            base = base * base;
            b >>= 1;
        }
        return ans;
    }
    
    ll div(ll x, ll y) {
        ll minn = 1e18;
        for (int i = 2; i * i <= x; ++i) {
            if (x % i == 0) {
                int t1 = 0, t2 = 0;
                while (x % i == 0) x /= i, ++t1;
                bool flag = false;
                while (y % i == 0) {
                    flag = true;
                    y /= i;
                    ++t2;
                }
                ll tot = qpow(i, t2 - t1 + 1);
                if (flag && tot < minn) minn = tot;
            }
        }
        if (x != 1 && y % x == 0) {
            int t = 0;
            bool flag = false;
            while (y % x == 0) {
                flag = true;
                y /= x;
                ++t;
            }
            ll tot = qpow(x, t);
            if (flag && tot < minn) minn = tot;
        }
        return minn;
    }
    
    int main() {
        scanf("%d", &t);
        while (t--) {
            read(p), read(q);
            if (p < q) std::cout << p << '
    ';
            if (p >= q) {
                if (p % q == 0) std::cout << p / div(q, p) << '
    ';
                else std::cout << p << '
    ';
            }
        }
        return 0;
    }
    

    D. Divide and Sum

    题意:

    给一个 (2n) 长的序列,将其随意分成两个长为 (n) 的序列 (p,q)(p) 按不减小的顺序排列,(q) 按不增加的顺序排列。计算每种分法的 (sumlimits_{i=1}^{n} mid p_i-q_i mid) 的和。

    题解:

    将原序列升序排序后分成两半,前面记为 (L),后面记为 (R),结论为不论怎么划分序列,贡献都是 (mid R-Lmid)

    证明
    假设存在一个位置 (i) 使得 (p_i,q_i) 都属于 (L)
    (p) 的前 (i) 个元素都属于 (L)
    (q) 的后面 (n-i+1) 个元素也都属于 (L)
    那么 (L) 中的元素至少有 (n + 1) 个,与事实不符。
    证毕。

    序列的分法一共有 (C_{2n}^{n}) 种,答案就是 (C_{2n}^{n} imes mid R-Lmid)

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #define M 300001
    #define int long long
    
    int mod = 998244353;
    int n, a[M], sum[M];
    
    int qpow(int a, int b) {
        int ans = 1, base = a;
        while (b) {
            if (b & 1) ans = base * ans % mod;
            base = base * base % mod;
            b >>= 1;
        }
        return ans % mod;
    }
    
    signed main() {
        scanf("%d", &n);
        for (int i = 1; i <= 2 * n; ++i) scanf("%d", &a[i]);
        std::sort(a + 1, a + 2 * n + 1);
        for (int i = 1; i <= 2 * n; ++i) {
            sum[i] = (sum[i - 1] + a[i]) % mod;
        }
        int fm, fz = 1;
        for (int i = 1; i <= 2 * n; ++i) {
            fz = fz * i % mod;
            if (i == n) fm = fz * fz % mod;
        }
        fm = qpow(fm, mod - 2);
        int mul = ((sum[2 * n] - sum[n]) - sum[n] + 10 * mod) % mod;
        std::cout << mul * (fz * fm % mod) % mod << '
    ';
        return 0;
    }
    
  • 相关阅读:
    NB-IOT终端应用场景
    开关量是什么信号,模拟量是什么信号
    模拟量设备为什么都用4~20mA传输信号
    物联网三大关键技术
    4~20mA.DC(1~5 V.DC)信号制的优点
    Lora在局域网中的优势
    NB-IoT终端在不同工作状态下的分析
    4G模块的串行AT命令发送未接收返回如何处理
    前端性能优化
    Tab:不可思议的CSS光标下划线跟随效果
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13912631.html
Copyright © 2011-2022 走看看