zoukankan      html  css  js  c++  java
  • Codeforces Round #680 (Div. 2, based on Moscow Team Olympiad)【ABCD】

    比赛链接:https://codeforces.com/contest/1445

    A. Array Rearrangment

    题意

    给定两个大小均为 (n) 的升序数组 (a)(b) ,判断能否重排数组 (b) 使得对任意 (i) 均满足 (a_i + b_i le x)

    题解一

    因为 (a) 为升序,所以将 (b) 按照降序排列判断即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int n, x;
            cin >> n >> x;
            vector<int> a(n);
            for (auto &x : a) cin >> x;
            vector<int> b(n);
            for (auto &x : b) cin >> x;
            sort(b.begin(), b.end(), greater<>());
            bool ok = true;
            for (int i = 0; i < n; i++) if (a[i] + b[i] > x) ok = false;
            cout << (ok ? "Yes" : "No") << "
    ";
        }
        return 0;
    }
    

    题解二

    (a) 不以升降序给出,则需要对 (a) 中的每个数在 (b) 中贪心查找最匹配的数。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int n, x;
            cin >> n >> x;
            vector<int> a(n);
            for (auto &x : a) cin >> x;
            multiset<int> st;
            for (int i = 0; i < n; i++) {
                int x;
                cin >> x;
                st.insert(x);
            }
            for (const auto &i : a) {
                auto it = st.upper_bound(x - i);
                if (it != st.begin() and *prev(it) <= x - i) st.erase(prev(it));
            }
            cout << (st.size() == 0 ? "Yes" : "No") << "
    ";
        }
        return 0;
    }
    

    B. Elimination

    题意

    决赛之前有两场选拔赛,已知:

    • 第一场选拔赛第 (100) 名的分数为 (a) ,第二场选拔赛所有人的分数都不少于 (b)
    • 第二场选拔赛第 (100) 名的分数为 (c) ,第一场选拔赛所有人的分数都不少于 (d)

    计算两场选拔赛的总分至少要多少才能进入决赛。

    题解

    假如刚好有两百人,那么可以进行以下合理假设:

    • 第一场前一百名分数为 (a) ,后一百名分数为 (b)
    • 第二场前一百名分数为 (c) ,后一百名分数为 (d)
    • 第二场的前一百名刚好为第一场的后一百名
    • 第二场的后一百名刚好为第一场的前一百名

    那么答案即 (max(a + b, c + d))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int a, b, c, d;
            cin >> a >> b >> c >> d;
            cout << max(a + b, c + d) << "
    ";
        }
        return 0;
    }
    
    

    C. Division

    题意

    给定两个数 (a)(b) ,计算满足以下条件的 (x) 的最大值:

    • (x)(a) 的因子
    • (x) 不是 (b) 的倍数

    题解

    最理想的 (x)(a) 本身,此时如果 (x)(b) 的倍数,那么只要将 (x) 内的某一质因子降到 (b) 中的幂次以下即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            long long a, b;
            cin >> a >> b;
            vector<int> p;
            long long n = b;
            for (int i = 2; i * i <= n; i++) {
                if (n % i == 0) {
                    p.push_back(i);
                    while (n % i == 0) n /= i;
                }
            }
            if (n > 1) p.push_back(n);
            long long ans = 1;
            for (auto i : p) {
                long long res = a;
                while (res % b == 0) res /= i;
                ans = max(ans, res);
            }
            cout << ans << "
    ";
        }
        return 0;
    }
    

    D. Divide and Sum

    题意

    给定一个大小为 (2n) 的数组,考虑将其拆分为两个等长的子序列 (p)(q) ,并将 (p) 以升序排列, (q) 以降序排列,同时定义 (f(p, q) = sum_{i = 1}^n |p_i - q_i|)
    计算所有可能子序列情况下的 (f(p, q)) 之和。

    题解

    不管怎么分,都是大的一半减去小的一半,将和记为 (sum) ,答案即 (C_{2n}^n imes sum)

    代码

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    constexpr int N = 1e6 + 100;
    constexpr int MOD = 998244353;
    
    int fac[N], inv[N];
    
    int binpow(int a, int b) {
        int res = 1;
        while (b) {
            if (b & 1) res = 1LL * res * a % MOD;
            a = 1LL * a * a % MOD;
            b >>= 1;
        }
        return res;
    }
    
    int C(int n, int m){
        if(m < 0 or m > n) return 0;
        return 1LL * fac[n] * inv[m] % MOD * inv[n - m] % MOD;
    }
    
    void Init(){
        fac[0] = 1;
        for (int i = 1; i < N; i++) fac[i] = 1LL * fac[i - 1] * i % MOD;
        inv[N - 1] = binpow(fac[N - 1], MOD - 2);
        for (int i = N - 2; i >= 0; i--) inv[i] = 1LL * inv[i + 1] * (i + 1) % MOD;
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        Init();
        int n;
        cin >> n;
        n *= 2;
        vector<int> a(n);
        for (auto &x : a) cin >> x;
        sort(a.begin(), a.end());
        int sum = 0;
        for (int i = 0; i < n / 2; i++) {
            sum += abs(a[i] - a[n - 1 - i]);
            sum %= MOD;
        }
        cout << C(n, n / 2) * sum % MOD << "
    ";
        return 0;
    }
    
    
  • 相关阅读:
    mysql去重
    java 实现一套流程管理、流转的思路(伪工作流)
    js模块加载框架 sea.js学习笔记
    使用js命名空间进行模块式开发
    二叉树的基本操作实现(数据结构实验)
    学生信息管理系统-顺序表&&链表(数据结构第一次作业)
    计算表达式的值--顺序栈(数据结构第二次实验)
    使用seek()方法报错:“io.UnsupportedOperation: can't do nonzero cur-relative seeks”错误的原因
    seek()方法的使用
    python中如何打印某月日历
  • 原文地址:https://www.cnblogs.com/Kanoon/p/13924958.html
Copyright © 2011-2022 走看看