AcWing第9场周赛题解

A. 3778. 平衡数组

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

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

解题思路:思维题。将所有元素加上 i 等价于将这个数减去 i。所以一种必定可行的方案就是一次操作第 2,3,,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 个数列的元素和为 sumi,然后对于 第 i 个数列中的数值为 x 的元素,删除 x 后数列中剩余元素和为 sumix,判断 sumix 在别的数列中是否存在(用 map),如果如在一个 sumjy=sumix,则答案就找到了。

示例程序:

#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. 先递增再递减。

所以可以定义状态 f1,i 表示区间 [1,i] 递增的情况下的最大和,f2,i 表示区间 [i,n] 递减的情况下的最大和,则答案为 max{f1,i+f2,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;
}
posted @   quanjun  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示