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

这是新的难度范围下的第一道题目。
进度
- 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';
}

浙公网安备 33010602011771号