zoukankan      html  css  js  c++  java
  • Codeforces Round#697(Div.3)补题

    题目链接:http://codeforces.com/contest/1475/problem/D

    题目大意为有n个app,每个app会占用ai的内存,以及具有bi的重要性。求卸载的app内存至少为m以上,同时重要性最小。

    这道题第一眼看上去应该就是重要性为1的app的数量要尽可能多,同时重要性为2的app的数量要尽可能少。

    第二步就是重要性为1且内存大的app数量要尽可能多,重要性为2且内存大的app数量要尽可能多。

    为此,我们需要对重要性为1和2的内存进行降序排列。

    先计算重要性为2的全部内存之和,并在此基础之上减去重要性2的内存加上重要性为1的内存,同时进行重要性的比较取最小值。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef long long ll;
     5 const int INF = 0x3f3f3f3f;
     6 const int N = 2e5 + 10;
     7 
     8 void solve()
     9 {
    10     int n, m;
    11     cin >> n >> m;
    12     vector<int> a, b;
    13     vector<int> v;
    14     for (int i = 0; i < n; i++) {
    15         int e;
    16         cin >> e;
    17         v.push_back(e);
    18     }
    19     for (int i = 0; i < n; i++) {
    20         int e;
    21         cin >> e;
    22         if (e == 1) {
    23             a.push_back(v[i]);
    24         }
    25         else {
    26             b.push_back(v[i]);
    27         }
    28     }
    29     sort(a.rbegin(), a.rend());
    30     sort(b.rbegin(), b.rend());
    31     ll sumb = accumulate(b.begin(), b.end(), 0ll);
    32     ll suma = 0;
    33     int r = b.size();
    34     int ans = INF;
    35     for (int i = 0; i <= a.size(); i++) {
    36         while (r > 0 && suma + sumb - b[r - 1] >= m) {
    37             r--;
    38             sumb -= b[r];
    39         }
    40         if (suma + sumb >= m) {
    41             ans = min(ans, 2 * r + i);
    42         }
    43         if (i != a.size()) {
    44             suma += a[i];
    45         }
    46     }
    47     cout << (ans == INF ? -1 : ans) << endl;
    48 }
    49 
    50 int main()
    51 {
    52     int t;
    53     cin >> t;
    54     while (t--) {
    55         solve();
    56     }
    57 }

     题目链接:http://codeforces.com/contest/1475/problem/E

    题目大意:n个人,每个人都有ai个粉丝。现在要从中选出k个人使他们的粉丝数最多。求选的方案数。

    很简单的一道题,只需要统计出粉丝数相同的有几个人,再按粉丝数从大到小排序,如果粉丝数相同的人的数量比k小,就遍历下一个粉丝数比它小的,同时k要减去该粉丝数相同的人数。如果比k大就粉丝数相同的人数里面选出k个人。

    #include <bits/stdc++.h>
     
    using namespace std;
    typedef long long ll;
    const int INF = 0x3f3f3f3f;
    const int N = 1e3 + 10;
    const int mod = 1e9 + 7;
     
    int c[N][N];
     
    void init()
    {
        for (int i = 0; i <= 1e3; i++) {
            c[i][i] = 1;
            c[i][0] = 1;
        }
        for (int i = 1; i <= 1e3; i++) {
            for (int j = 1; j <= 1e3; j++) {
                c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
            }
        }
    }
     
    void solve()
    {
        int n, k;
        cin >> n >> k;
        map<int,int> m;
        vector<int> v;
        for (int i = 0; i < n; i++) {
            int x;
            cin >> x;
            if (!m[x]) {
                v.push_back(x);
            }
            m[x]++;
        }
        //cout << v.size() << endl;
        sort(v.rbegin(), v.rend());
        ll ans = 1;
        for (int i = 0; i < v.size(); i++) {
            if (m[v[i]] < k) {
                k -= m[v[i]];
            }
            else {
                ans *= c[m[v[i]]][k] % mod;
                break;
            }
        }
        cout << ans << endl;
    }
     
    int main()
    {
        init();
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
    }
    

      题目链接:http://codeforces.com/contest/1475/problem/F

    题目大意:给定两个01矩阵,问是否能从第一个矩阵变为第二个矩阵。操作为:把某一列的所有元素都与1异或或者把每一行都与1异或。因此只需要按列模拟一遍,再按行模拟一遍。

    #include <bits/stdc++.h>
     
    using namespace std;
    typedef long long ll;
    const int INF = 0x3f3f3f3f;
    const int N = 1e3 + 10;
    const int mod = 1e9 + 7;
     
     
     
    void solve()
    {
        int n;
        cin >> n;
        string s = "";
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                char x;
                cin >> x;
                s += x;
            }
        }
        char c = getchar();
        string s1 = "";
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                char x;
                cin >> x;
                s1 += x;
            }
        }
        for (int i = 0; i < n; i++) {
            if (s[i] != s1[i]) {
                for (int j = i; j < n*n; j += n) {
                    if (s[j] == '0') {
                        s[j] = '1';
                    }
                    else {
                        s[j] = '0';
                    }
                }
            }
        }
        for (int i = n; i < n * n; i += n) {
            if (s[i] != s1[i]) {
                for (int j = i; j < i+n; j++) {
                    if (s[j] == '0') {
                        s[j] = '1';
                    }
                    else {
                        s[j] = '0';
                    }
                }
            }
        }
        if (s == s1) {
            cout << "Yes" << endl;
        }
        else {
            cout << "No" << endl;
        }
    }
     
    int main()
    {
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
    }
    

      题目链接:http://codeforces.com/contest/1475/problem/G

    题目大意,给n个数,求要使两两可以相除要移除的最小元素数量。其实就是求可以两两相除的最大元素个数。

    这道题。。。一个sort排序卡了我半天,最后看题解只需要从1筛到2e5就可以。。。

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int INF = 0x3f3f3f3f;
    const int N = 2e5 + 10;
    const int mod = 1e9 + 7;
    
    int a[N], dp[N];
    
    void solve()
    {
        int n;
        cin >> n;
        memset(a, 0, sizeof(a));
        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < n; i++) {
            int x;
            cin >> x;
            a[x]++;
        }
        int ans = -INF;
        for (int i = 1; i <N; i++) {
            if (a[i]) {
                dp[i] += a[i];
                for (int j = i + i; j <= N; j += i) {
                    dp[j] = max(dp[i], dp[j]);
                }
            }
            ans = max(dp[i], ans);
        }
        cout << n - ans << endl;
    }
    
    int main()
    {
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
    }
    

      

  • 相关阅读:
    P1144 最短路计数 题解 最短路应用题
    C++高精度加减乘除模板
    HDU3746 Teacher YYF 题解 KMP算法
    POJ3080 Blue Jeans 题解 KMP算法
    POJ2185 Milking Grid 题解 KMP算法
    POJ2752 Seek the Name, Seek the Fame 题解 KMP算法
    POJ2406 Power Strings 题解 KMP算法
    HDU2087 剪花布条 题解 KMP算法
    eclipse创建maven项目(详细)
    maven的作用及优势
  • 原文地址:https://www.cnblogs.com/Drqidian/p/14332847.html
Copyright © 2011-2022 走看看