2025.03.21 CW 模拟赛 A. 军训
A. 军训
构造.
思路
由于 \(k \le n\), 所以每一次操作必须复位至少一个数.

如图, 其中 A, B, C 块可能是空的.
假设 \(i\) 这个数在 A, B 块之间, \(i + 1\) 在 B, C 块之间, 考虑如何将 \(i\) 放在 \(i + 1\) 前面.
可以发现, 我们将 A 单独分一组, \(i\) 和 B 块分一组, \(i + 1\) 分一组, C 分一组进行翻转操作就行了.
需要注意的是, 对于类似 8 4 5 6 7 1 2 3 这种序列, 当我们要复位 8 和 7 时, 我们需要将 4 5 6 7 看作一整块来进行操作, 而不能将 7 单独看作一块, 否则可能打乱原本已经复位好的数.
vector<int> t;
fill(pos, pos + n + 1, 0);
for (int i = 1, j; i <= n; ++i) {
if (pos[a[i] + 1]) {
j = i;
while (j and a[j] - a[j - 1] == 1) {
--j;
}
if (pos[a[i] + 1] ^ 1) {
t.push_back(pos[a[i] + 1] - 1);
reverse(a + 1, a + pos[a[i] + 1]);
}
t.push_back(j - pos[a[i] + 1]);
reverse(a + pos[a[i] + 1], a + j);
t.push_back(i - j + 1);
reverse(a + j, a + i + 1);
if (i ^ n) {
t.push_back(n - i);
reverse(a + i + 1, a + n + 1);
}
break;
}
pos[a[i]] = i;
}
opt.push_back(t);
reverse(a + 1, a + n + 1);
结语
考场上想到了每次使得 \(i\) 和 \(i + 1\) 相邻, 但是是从 1 到 \(n\) 挨个操作的, 导致操作次数上限为 \(2n\)...

浙公网安备 33010602011771号