zoukankan      html  css  js  c++  java
  • Codeforces Round #683 (Div. 2, by Meet IT)【ABCD】

    比赛链接:https://codeforces.com/contest/1447

    A. Add Candies

    题意

    (1)(n) 个袋子里依次有 (1)(n) 个糖果,可以选择操作 (m) 次,第 (i) 次操作可以:

    • 选择一个袋子,除了这个袋子外其他袋子都再放入 (i) 个糖果

    问是否存在一种操作序列,使得最终 (n) 个袋子内的糖果数相同。

    题解

    将每个袋子内的糖果都加到 (frac{n(n + 1)}{2}) 个。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            cout << n << "
    ";
            for (int i = 1; i <= n; i++) cout << i << " 
    "[i == n];
        }
        return 0;
    }
    

    B. Numbers Box

    题意

    给出一个 (n imes m) 的矩阵,每次操作可以:

    • 选择任意两个相邻元素各乘以 (-1)

    可以操作任意次,问矩阵中所有元素之和的最大值为多少。

    题解

    有零的话可以把所有负数都变为正,答案即所有数的绝对值之和。
    否则如果负数个数为奇数,需要减去一个绝对值最小的数。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int n, m;
            cin >> n >> m;
            vector<int> a(n * m);
            int sum = 0, neg = 0, zero = 0, mi = INT_MAX;
            for (auto &x : a) cin >> x, sum += abs(x), neg += x < 0, zero += x == 0, mi = min(mi, abs(x));
            if (neg & 1 and zero == 0) sum -= 2 * mi;
            cout << sum << "
    ";
        }
        return 0;
    }
    

    C. Knapsack

    题意

    有一个承重为 (W) 的背包,另有 (n) 个物品,分别重 (w_i) ,判断能否找到一些物品使得它们的总重 (C) 满足 (lceil frac{W}{2} ceil le C le W) ,如果可以,输出这些物品的编号。

    题解

    首先去除 (w_i > W) 的元素,然后如果有单个 (w_i ge lceil frac{W}{2} ceil) 直接选取即可,此时余下的 (w_i) 均小于 (lceil frac{W}{2} ceil) ,如果它们的总和小于 (lceil frac{W}{2} ceil) 则无解,否则一定存在满足题意的序列,依次选取至不小于 (lceil frac{W}{2} ceil) 即可。

    证明

    两个小于 (lceil frac{W}{2} ceil) 的数相加有两种情况:

    • 小于 (lceil frac{W}{2} ceil)
    • 不小于 (lceil frac{W}{2} ceil) 且小于 (W)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            long long n, W;
            cin >> n >> W;
            long long mid_W = (W + 1) / 2;
            vector<int> w(n);
            for (auto &x : w) cin >> x;
            vector<int> p(n);
            iota(p.begin(), p.end(), 0);
            sort(p.begin(), p.end(), [&](int x, int y) {
                return w[x] < w[y];
            });
            while (p.size() and w[p.back()] > W) {
                p.pop_back();
            }
            if (p.empty() or accumulate(p.begin(), p.end(), 0LL, [&](long long sum, int x) { return sum + w[x]; }) < mid_W) {
                cout << -1 << "
    ";
                continue;
            }
            if (w[p.back()] >= mid_W) {
                cout << 1 << "
    " << p.back() + 1 << "
    ";
                continue;
            }
            vector<int> v;
            long long sum = 0;
            for (auto i : p) {
                sum += w[i], v.push_back(i);
                if (sum > mid_W) break;
            }
            cout << v.size() << "
    ";
            for (auto i : v) cout << i + 1 << " 
    "[i == v.back()];
        }
        return 0;
    }
    

    D. Catching Cheaters

    题意

    给出两个字符串 (s, t) ,定义: (f(s, t) = 4 cdot LCS(s, t) - |s| - |t|)
    找出 (s, t) 所有连续子串匹配的可能情况中最大的函数值。

    题解

    (dp_{ij}) 的含义为以 (s_i)(t_j) 结尾的两个连续子串匹配的最大函数值。
    状态转移方程分为两种情况:

    • (s_i = t_j)
      • 可以在以 (s_{i - 1})(t_{j - 1}) 结尾的两个子串尾部各添加一个字符,即 (dp_{ij} = dp_{i - 1 j - 1} + 2)
      • 也可以在两个空串尾部添加一个字符,即 (dp_{ij} = 0 + 2)
    • (s_i e t_j)
      • 可以在以 (s_{i - 1})(t_{j - 1}) 结尾的一个子串尾部添加一个字符,即 (dp_{ij} = max(dp_{i - 1 j}, dp_{i j - 1}) - 1)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n, m;
        cin >> n >> m;
        string s, t;
        cin >> s >> t;
        vector<vector<int>> dp(n + 1, vector<int>(m + 1));
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (s[i - 1] == t[j - 1]) dp[i][j] = max(0, dp[i - 1][j - 1]) + 2;
                else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) - 1;
                ans = max(ans, dp[i][j]);
            }
        }
        cout << ans << "
    ";
        return 0;
    }
    
  • 相关阅读:
    如何在Linux下的C++文件使用GDB调试
    21天学通C++(C++程序的组成部分)
    嵌入式Linux应用程序开发
    项目部署的问题
    未解决
    报错
    随笔
    逆向工程出现的错误1
    jpa学习
    springmvc整合mybaits
  • 原文地址:https://www.cnblogs.com/Kanoon/p/13991460.html
Copyright © 2011-2022 走看看