• Codeforces Round #697 (Div. 3) A -D 解题报告


    A. Odd Divisor

    题意:

    判断一个数是否存在 (>1) 的奇因数。

    思路:

    将一个数分解质因数显然可以发现除 (2) 都是奇数,那么我们只需要判断该数是不是 (2) 的整数次幂即可。

    代码:
    int main() {
    
        int t; cin >> t;
        while (t --) {
            ll n; cin >> n;
            while (n % 2 == 0) n >>= 1;
            if (n == 1) puts("NO");
            else puts("YES");
        }
        return 0;
    }
    

    B. New Year's Number

    题意:

    给定一个数 (n),问你能否构造如下等式:(n = 2020 imes x + 2021 imes y)。( (x, y) 均为大于等于零的整数)

    思路:

    将上述等式变换:(n = 2020 imes(x+y) + y)

    那么显然 (x + y = frac{n}{2020})(y = n \% 2020)

    显然 (y > x + y) 时等式不成立。

    代码:
    int main() {
    
        int t; cin >> t;
        while (t --) {
            int n; cin >> n;
            int x = n / 2020;
            int y = n % 2020;
            if (y > x) puts("NO");
            else puts("YES");
        }
        return 0;
    }
    

    C. Ball in Berland

    题意:

    给定男女的匹配关系,从中选出两对男女(没有重复的人),问有几种选法?

    思路:

    由于固定了只选择两对,那么我们可以枚举其中的一对关系 (a),而另一对中的人一定是 (a) 中没有出现过的,可以利用容斥原理,用 (k) - (a) 中出现过的人的关系数 + 1 即另一对可以选择的数量。(+1是因为会重复减一次)。

    代码:
    map<int, int> man, woman;
    
    vector<int> v_man, v_woman;
    
    int main() {
    
        int t; cin >> t;
        while (t --) {
            man.clear();
            woman.clear();
            v_man.clear();
            v_woman.clear();
            int a, b, k;
            cin >> a >> b >> k;
            for (int i = 1; i <= k; i ++) {
                int x; cin >> x;
                v_man.pb(x);
                man[x] ++;
            }
            for (int i = 1; i <= k; i ++) {
                int x; cin >> x;
                v_woman.pb(x);
                woman[x] ++;
            }
            ll ans = 0;
            for (int i = 0; i < k; i ++) {
                int tmp_man = v_man[i];
                int tmp_woman = v_woman[i];
                ans += k - man[tmp_man] - woman[tmp_woman] + 1;
            }
            cout << ans / 2 << endl;
        }
        return 0;
    }
    

    D. Cleaning the Phone

    题意:

    (n) 个应用程序,第 (i) 个占用的内存为 (a_i),删除它的花费为 (b_i)。要求你至少腾出 (m) 的内存,问最少花费是多少?如果删光了所有应用都不行,就输出 -1

    思路:

    由于 (b_i) 的取值只有 (1)(2)。那么我们就可以根据这个来分组,然后按内存从大到小排序,求一个前缀和,然后枚举某一组,用二分算出另一组。注意只选取某一组的特殊情况。

    代码:
    bool cmp(ll a, ll b) { return a > b; }
    
    int main() {
    
        int t; cin >> t;
        while (t --) {
            int n, m;
            vector<ll> memory, v1, v2, sum1, sum2;
            cin >> n >> m;
            ll sum = 0;
            for (int i = 1; i <= n; i ++) {
                int x; cin >> x;
                sum += x;
                memory.pb(x);
            }
            for (int i = 1; i <= n; i ++) {
                int x; cin >> x;
                if (x == 1) {
                    v1.pb(memory[i - 1]);
                } else {
                    v2.pb(memory[i - 1]);
                }
            }        
            if (sum < m) {
                puts("-1");
                continue;
            }
            sort(all(v1), cmp);
            sort(all(v2), cmp);
            int len_v1 = v1.size();
            int len_v2 = v2.size();
            ll pre = 0;
            for (int i = 0; i < len_v1; i ++) {
                sum1.pb(pre + v1[i]);
                pre = sum1[i];
            }
            pre = 0;
            for (int i = 0; i < len_v2; i ++) {
                sum2.pb(pre + v2[i]);
                pre = sum2[i];
            }
            int ans = INF;
            int len_sum1 = sum1.size();
            int len_sum2 = sum2.size();
            // 全部选 2 的
            int idx = lower_bound(all(sum2), m) - sum2.begin();
            if (idx < len_sum2) ans = min(ans, (idx + 1) * 2);
            for (int i = 0; i < len_sum1; i ++) {
                ll tmp1 = sum1[i];
                ll tmp2 = m - tmp1;
                if (tmp2 <= 0) {
                    ans = min(ans, i + 1);
                    break;
                } else {
                    int idx = lower_bound(all(sum2), tmp2) - sum2.begin();
                    if (idx < len_sum2) ans = min(ans, i + 1 + (idx + 1) * 2);
                }
            }
            cout << ans << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    PHP mysqli_get_client_version() 函数
    PHP mysqli_get_client_stats() 函数
    两台服务器配置互信
    (转)SQL server 容易让人误解的问题之 聚集表的物理顺序问题
    DML操作对索引的影响
    sqlserver 常用语句
    聚集索引
    表扫描
    sqltext的参数化处理
    sqlserver的执行计划
  • 原文地址:https://www.cnblogs.com/nonameless/p/14343504.html
Copyright © 2020-2023  润新知