[CP / Codeforces] B. Sorted Adjacent Differences (Div. 2) - 1200*

B. Sorted Adjacent Differences

前言

最近按过题人数降序狂刷 1000* 构造题,把看题解的比例控制在 30% 左右,平均解题时间 15 分钟,效果良好(基本上能速切 Div.2 AB 了),因此决定将难度范围扩展至 1000* - 1400*。这个范围下过题人数大于 10000 的题目大致有 250 道,希望刷完它们能对自己的思维敏捷度的提升有较大帮助。

image

这是新的难度范围下的第一道题目。

进度

  • 26:06.74 - AC

分析

题目给的条件很怪,乍看无从下手。起先想的是去掉绝对值符号,但又发现要处理的情况非常多,遂放弃。虽然潜意识里觉得这种题目需要排序,可是盯着排序后的样例看了半天也没看出什么。

再次阅读题目,发现一句关键的话:

\[\mathrm{It's\ always\ possible\ to\ find\ such\ rearrangement.} \]

这句话让几乎准备去看题解的我又燃起了希望。如果我能从特殊的数据中发现某种规律,那么这一规律很可能对一般的数据也适用。

于是我又盯着样例看。为什么我一开始会想到排序呢?因为题目中的条件作用的对象是元素之间的 “距离”,于是自然想到计算距离的最小值和最大值,即便这些边界计算出来不一定有用。通过排序,我可以通过对输入数组的一次扫描得到元素之间的最小距离,而最大距离就等于最后一个元素减去第一个元素。

到这里似乎又卡住了。

回到一开始的问题。怎么保证相邻元素之间的距离是不下降的呢?如果能让当前这一对相邻元素的距离把前一对相邻元素的距离 “包裹” 在里面,是否就能保证这一点呢?我想到之前计算最小距离的过程。如果从已排序数组中间的两个元素开始,左右交错地取元素……

然后本题就解出来了。

代码

void solve() {
    int n = 0;
    std::cin >> n;

    std::vector<int> v(n);
    for (int i = 0; i < n; i++) {
        std::cin >> v[i];
    }

    std::ranges::sort(v);
    int d = 0, cur = (n + 1) / 2 - 1, flag = 1;
    while (cur + d >= 0 && cur + d < n) {
        std::cout << v[cur + d] << ' ';
        cur += d;
        d = (std::abs(d) + 1) * flag;
        flag = -flag;
    }
    std::cout << '\n';
}
posted @ 2024-07-25 10:50  ZXPrism  阅读(45)  评论(0)    收藏  举报