zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    windows phone 7 客户端和web的交互(WebBrowser的使用)
    Android绑定对象到ListView中(知识积累)
    ASP.Net绑定数据到树[TreeView]献给善忘的,依然是菜鸟的我们。
    windows phone 7 通过Post提交URL到服务器,从服务器获取数据(比如登陆时候使用)
    Android从网络下载XML输出流或者字符串(知识积累)
    在GridView和Repeater上显示序号[最简单的方式,也是最实用的方式]献给善忘的依然是的菜鸟我们
    windows phone 7 通过麦克风录音,并且播放
    windows phone 7 定位(获取经纬度),然后找到经纬度所在的位置(城市信息)
    C# winform 登陆等待中. [异步请求]BackgroundWorker组件的使用
    Android解析XML之XmlPullParser
  • 原文地址:https://www.cnblogs.com/nonameless/p/14343504.html
Copyright © 2011-2022 走看看