2025.03.21 CW 模拟赛 A. 军训

A. 军训

构造.

思路

由于 \(k \le n\)​, 所以每一次操作必须复位至少一个数.

image.png

如图, 其中 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\)...

posted @ 2025-03-24 11:30  Steven1013  阅读(9)  评论(0)    收藏  举报