专栏文章

CF2148D 题解

CF2148D题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mintlexl
此快照首次捕获于
2025/12/02 08:08
3 个月前
此快照最后确认于
2025/12/02 08:08
3 个月前
查看原文
更佳的阅读体验:CF2148D 题解

简要题意:有 nn 块田地,每块田地有 aia_i 朵蒲公英。若访问的田地的 aia_i 为奇数,割草机会切换开关状态。如果割草机是开着的,就会割掉这块田地的所有蒲公英。可以任意排列访问顺序,问最多能割掉多少朵蒲公英。
首先可以确定的是,只要有 aia_i 为奇数的田地,那么第一个访问奇数的田地,之后一次性访问所有偶数的田地,那么所有 aia_i 为偶数的田地是一定可以被割掉的。
接下来考虑如何安排 aia_i 为奇数的田地的顺序。为了使得总和尽可能大,我们考虑一种类似「大、小、大、小、……」的安排方案。这样,访问到 aia_i 较大的田地时,割草机总是开的。
记奇数个数为 nn。如果奇数个数非零,答案就是所有偶数的和加上最大的 n2\left \lceil \dfrac{n}{2} \right \rceil 个奇数的和;否则答案为 00
CPP
#include <iostream>
#include <algorithm>
using namespace std;
using ll = long long;

const int N = 2e5 + 10;
int t, n;
ll a, ans;
basic_string<ll> odd, even;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    for (cin >> t; t; --t) {
        ans = 0;
        odd.clear(), even.clear();
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            cin >> a;
            if (a & 1) odd += a;
            else even += a;
        } if (!odd.size()) {
            cout << "0\n";
            continue;
        } for (auto p : even) ans += p;
        sort(odd.begin(), odd.end(), greater<>());
        for (int i = 0; i < (odd.size() + 1) / 2; ++i) ans += odd[i];
        cout << ans << '\n';
    } return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...