• AcWing第9场周赛题解


    A. 3778. 平衡数组

    题目链接:https://www.acwing.com/problem/content/3781/

    题目大意:\(m\) 次题目要求的操作使最终所有数都相等。

    解题思路:思维题。将所有元素加上 \(i\) 等价于将这个数减去 \(i\)。所以一种必定可行的方案就是一次操作第 \(2, 3, \ldots, n\)

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    
    int T, n;
    
    int main() {
        cin >> T;
        while (T--) {
            cin >> n;
            cout << n-1 << endl;
            for (int i = 2; i <= n; i++) {
                if (i > 2) cout << " ";
                cout << i;
            }
            cout << endl;
        }
        return 0;
    }
    
    

    B. 3779. 相等的和

    题目链接:https://www.acwing.com/problem/content/3782/

    题目大意:略。

    解题思路:枚举。先求出每个序列的和,设第 \(i\) 个数列的元素和为 \(sum_i\),然后对于 第 \(i\) 个数列中的数值为 \(x\) 的元素,删除 \(x\) 后数列中剩余元素和为 \(sum_i - x\),判断 \(sum_i - x\) 在别的数列中是否存在(用 map),如果如在一个 \(sum_j - y = sum_i - x\),则答案就找到了。

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 5;
    int k, n, a[maxn];
    map<int, pair<int, int>> mp;
    
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        cin >> k;
        for (int i = 1; i <= k; i++) {
            cin >> n;
            int sum = 0;
            for (int j = 1; j <= n; j++) {
                cin >> a[j];
                sum += a[j];
            }
            for (int j = 1; j <= n; j++) {
                if (mp.find(sum - a[j]) != mp.end()) {
                    pair<int, int> v = mp[sum - a[j]];
                    if (v.first != i) {
                        cout << "YES" << endl;
                        cout << v.first << " " << v.second << endl;
                        cout << i << " " << j << endl;
                        return 0;
                    }
                }
                else
                    mp[sum - a[j]] = {i, j};
            }
        }
        cout << "NO" << endl;
        return 0;
    }
    

    题目链接:

    题目大意:

    解题思路:(下面说的递增/递减指的都是非严格单调递增/递减)

    考虑到最终的数列只有如下三种情况:

    1. 全部递增;
    2. 全部递减;
    3. 先递增再递减。

    所以可以定义状态 \(f_{1,i}\) 表示区间 \([1,i]\) 递增的情况下的最大和,\(f_{2,i}\) 表示区间 \([i,n]\) 递减的情况下的最大和,则答案为 \(\max\{ f_{1,i} + f_{2,i+1} \}\)

    实现时可以使用 单调队列 优化。

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 5e5 + 5;
    int n;
    long long a[maxn], f1[maxn], f2[maxn];
    deque<int> que;
    
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        // 先从前往后求 f1[i]
        for (int i = 1; i <= n; i++) {
            while (!que.empty() && a[que.back()] > a[i]) que.pop_back();
            int p = que.empty() ? 0 : que.back();
            f1[i] = f1[p] + (i - p) * a[i];
            que.push_back(i);
        }
        // 再从后往前求 f2[i]
        que.clear();
        for (int i = n; i >= 1; i--) {
            while (!que.empty() && a[que.back()] > a[i]) que.pop_back();
            int p = que.empty() ? (n+1) : que.back();
            f2[i] = f2[p] + (p - i) * a[i];
            que.push_back(i);
        }
        int x = 1;  // 最大值下标
        for (int i = 2; i <= n; i++)
            if (f1[i] + f2[i] - a[i] > f1[x] + f2[x] - a[x])
                x = i;
        long long y = a[x];
        for (int i = x-1; i >= 1; i--) y = a[i] = min(y, a[i]);
        y = a[x];
        for (int i = x+1; i <= n; i++) y = a[i] = min(y, a[i]);
        for (int i = 1; i <= n; i++) {
            if (i > 1) cout << " ";
            cout << a[i];
        }
        cout << endl;
        return 0;
    }
    
  • 相关阅读:
    sqoop
    HBase API操作
    Hbase 01-安装| shell操作
    Azkaban
    Kafka-API
    Oozie
    Kafka Manager| KafkaMonitor
    kafka工作流程| 命令行操作
    CDH| HUE的自动化安装部署
    Impala
  • 原文地址:https://www.cnblogs.com/quanjun/p/16121082.html
Copyright © 2020-2023  润新知