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;
    }
    
  • 相关阅读:
    python之squid实现免费 IP代理 (windows win7 单机 本机 本地 正向代理 区分 HTTPS)
    python之PIL 二值图像处理和保存
    python之GIL release (I/O open(file) socket time.sleep)
    python之多线程 threading.Lock() 和 threading.RLock()
    python之GIL官方文档 global interpreter lock 全局解释器锁
    python多线程之t.setDaemon(True) 和 t.join()
    python之工作目录和文件引用
    python 代理
    原 浅谈移动端开发--物理像素和逻辑像素
    解决移动端页面在苹果端滑不到底部的问题
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/14336421.html
Copyright © 2011-2022 走看看