zoukankan      html  css  js  c++  java
  • Codeforces Round #697 (Div. 3) A~E题解

    写在前边

    状态及其不佳,很累很困,还好(unrated)

    链接:Codeforces Round #697 (Div. 3)

    A. Odd Divisor

    链接:A题链接

    题目大意:

    判断一个数是否有奇数因子。

    思路

    一开始挺懵的,然后自己推了一下,发现只有(2)的幂才不会有奇数因子,因此本题只需要判断是否是二的幂即可,利用位运算,(x & (x - 1))

    代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    
    using namespace std;
    
    #define Inf 0x3f3f3f3f
    #define PII pair<int, int>
    #define PLL pair<long, long>
    
    typedef long long ll;
    typedef unsigned long long ULL;
    typedef vector<long long> VLL;
    typedef vector<int> VI;
    
    void solve() {
        ll n;
        cin >> n;
        if (n & (n - 1)) {
            puts("YES");
        } else {
            puts("NO");
        }
    }
    
    int main()
    {
        ios::sync_with_stdio(false), cin.tie(0);
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
        return 0;
    } 
    

    B. New Year's Number

    链接:B题链接

    题目大意:

    判断一个数(n)是否可以由(a)(2021)(b)(2020)组成。

    思路

    既然由(2020)(2021)组成,那么只需要判断(n)(2020)取模后得到的数是否可以由(n / 2020)(1)组成即可,即((n \% 2020) <= (n / 2020))

    代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    
    using namespace std;
    
    #define Inf 0x3f3f3f3f
    #define PII pair<int, int>
    #define PLL pair<long, long>
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector<long long> VLL;
    typedef vector<int> VI;
    
    void solve() {
        int n;
        cin >> n;
        if ((n % 2020) <= (n / 2020)) {
            puts("YES");
        } else {
            puts("NO");
        }
    }
    
    int main()
    {
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
        return 0;
    }
    

    C. Ball in Berland

    链接:C题链接

    题目大意:

    (a)个男生,(b)个女生,一个男生一个女生组合起来跳舞,并且要求选出两对,给出(k)对男女组合,求有多少种组合方式。

    思路

    可以两重直接循环枚举,枚举到([a, b])的时候,二重循环中判断不包含(a,b)顶点的都可以加到答案中,但是直接枚举肯定超时,因此优化一下我们就可以预处理出(a)的出度(degreeA[a])(b)的出度(degreeB[b]),那么一重循环枚举到([a, b])我们可以直接找到不符合条件的有几个,即(degreeA[a] + degreeB[b] - 1),一共有(k)对那么符合条件的就有(k - (degreeA[a] + degreeB[b] - 1)),因此就从(O(n^2))优化到了(O(n)),最后再将答案除以(2)即可,因为每个顶点都算了两遍。

    代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    
    using namespace std;
    
    #define Inf 0x3f3f3f3f
    #define PII pair<int, int>
    #define PLL pair<long, long>
    
    typedef long long ll;
    typedef unsigned long long ULL;
    typedef vector<long long> VLL;
    typedef vector<int> VI;
    
    const int N = 2e5 + 10;
    int edga[N], edgb[N];
    ll out_degreeA[N], out_degreeB[N];
    
    void solve() {
        int a, b, k;
        cin >> a >> b >> k;
        for (int i = 1; i <= k; i++) {
            cin >> edga[i];
            out_degreeA[edga[i]]++;
        }
        for (int i = 1; i <= k; i++) {
            cin >> edgb[i];
            out_degreeB[edgb[i]]++;
        }
        ll res = 0;
        for (int i = 1; i <= k; i++) {
            res += k - (out_degreeA[edga[i]] + out_degreeB[edgb[i]] - 1);
        }
        cout << res / 2 << endl;
        memset(out_degreeA, 0, sizeof out_degreeA);
        memset(out_degreeB, 0, sizeof out_degreeB);
    }
    
    int main()
    {
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
    
        return 0;
    } 
    

    D. Cleaning the Phone

    链接:D题链接

    题目大意:

    清理手机问题,每个(app)占用内存(a_i),它相应的实用度有(b_i) ((b_i只能为1或2)),那么总的实用度就是(b_i)的和,现在要清理内存,要求清理出至少(m)的内存,损失最少实用度,求出损失的最少实用度,若没有则输出(-1)

    思路

    很明显的贪心策略就是优先删除实用度为(1)并且占内存比较大的,再者就是删除实用度为(2)占内存比较大的,而但是毕竟选择的不是一两个(app),因此为了解决这个问题可以将实用度为1或者2的分成两个数组,然后求其前缀和,最好的方案就是再能达到需求的情况下尽可能少的卸载实用度为(2)(app),因此从大到小枚举实用度为(2)(app),然后剩下就是(m - preSum2),那么另一边就用二分来选择(preSum1),维护一个(res)始终为最小方案。

    代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    #include <climits>
    
    using namespace std;
    
    #define Inf 0x3f3f3f3f
    #define PII pair<int, int>
    #define PLL pair<long, long>
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector<long long> VLL;
    typedef vector<int> VI;
    
    void solve() {
        int n, m;
        cin >> n >> m;
        vector<LL> v(n + 1), preSum1, preSum2;
        preSum1.push_back(0), preSum2.push_back(0);
        for (int i = 1; i <= n; i++) {
            cin >> v[i];
        }
        for (int i = 1; i <= n; i++) {
            int c;
            cin >> c;
            if (c == 1) {
                preSum1.push_back(v[i]);
            }
            else if (c == 2) {
                preSum2.push_back(v[i]);
            }
        }
    
        sort(preSum2.rbegin(), preSum2.rend() - 1), sort(preSum1.rbegin(), preSum1.rend() - 1);
        
        for (int i = 1; i < preSum1.size(); i++) {
            preSum1[i] += preSum1[i - 1];
        }
        for (int i = 1; i < preSum2.size(); i++) {
            preSum2[i] += preSum2[i - 1];
        }
    
        LL res = INT_MAX;
        for (int i = preSum2.size() - 1; i >= 0; i--) { //从大到小枚举
            LL aim = m - preSum2[i];
            LL l = 0, r = preSum1.size(); 
            while (l < r) {
                 LL mid = l + r >> 1;
                if (preSum1[mid] >= aim) {
                    res = min(res, i * 2 + mid);
                    r = mid;
                }
                else {
                    l = mid + 1;
                }
            }
        }
        cout << (res == INT_MAX ? -1 : res) << endl;
    }
    
    int main()
    {
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
    
        return 0;
    }
    

    E. Advertising Agency

    链接:E题链接

    题目大意:

    一个人从(n)个博主里选(k)个来带货,那么她当然是优先选择粉丝多的博主了,问有多少种选择方案。

    思路

    (cnt[x])为拥有(x)个粉丝的博主,那么我们肯定优先从粉丝多的博主选了,例如要求选(k)个,已经选了(m)个,还剩下(k - m)个需要选,那么现在(cnt[x] >= k - m),因此只需要从cnt[x]里选k-m个即可,即求组合数,因为数据范围很小,可以直接用递推式即可:(C_a^b = C_{a-1}^{b} + C_{a-1}^{b-1})

    代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    
    using namespace std;
    
    #define Inf 0x3f3f3f3f
    #define PII pair<int, int>
    #define PLL pair<long, long>
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector<long long> VLL;
    typedef vector<int> VI;
    
    const int mod = 1e9 + 7;
    const int N = 1010;
    int c[N][N];
    
    void init() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j <= i; j++) {
                if (!j) {
                    c[i][j] = 1;
                } else {
                    c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
                }
            }
        }
    }
    
    void solve() {
        int k, n;
        cin >> n >> k;
        vector<int> cnt(n + 1);
        for (int i = 1; i <= n; i++) {
            int x;
            cin >> x;
            cnt[x]++;
        }   
        init();
        for (int i = n; i >= 1; i--) {
            if (cnt[i] >= k) {
                cout << c[cnt[i]][k] << endl;
                return;
            } else {
                k -= cnt[i];
            }
        }
    }
    
    int main()
    {
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    AtCoder Beginner Contest 205
    Codeforces Round #725 (Div. 3)
    Educational Codeforces Round 110 (Rated for Div. 2)【A
    Codeforces Round #722 (Div. 2)
    AtCoder Beginner Contest 203(Sponsored by Panasonic)
    AISing Programming Contest 2021(AtCoder Beginner Contest 202)
    PTA 520 钻石争霸赛 2021
    Educational Codeforces Round 109 (Rated for Div. 2)【ABCD】
    AtCoder Beginner Contest 200 E
    Educational Codeforces Round 108 (Rated for Div. 2)【ABCD】
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/14336421.html
Copyright © 2011-2022 走看看