0%

The 2026 ICPC Latin America Championship(2026 拉丁美洲决赛)-Gym-106416——A. Ants on a Ring(这种题目就是推性质)(这个环,一定要想办法化曲为直!一定要在一个地方,把环变成一条直线)

题目大意

题目描述
在一个圆上有 NN 只蚂蚁。圆被顺时针划分为 LL 个位置,编号为 11LL,其中位置 LL 与位置 11 相邻。
每只蚂蚁初始站在不同的位置上,并且都需要到达各自不同的目标位置。
在每一秒内,每只蚂蚁可以选择:

  • 停留在原地。

  • 顺时针或逆时针移动到相邻的位置。

在任何时刻(包括在两个位置之间移动的过程中),任意两只蚂蚁都不能处于同一个位置。例如,如果某只蚂蚁在某一秒内顺时针从位置 11 移动到位置 22,那么在同一秒内,其他蚂蚁不能进行以下操作:

  • 停留在位置 22(这会导致两只蚂蚁在位置 22 相遇)。

  • 逆时针从位置 33 移动到位置 22(这会导致两只蚂蚁在位置 22 相遇)。

  • 逆时针从位置 22 移动到位置 11(这会导致两只蚂蚁在位置 11 和位置 22 之间相遇)。

你需要判断是否有可能让所有蚂蚁都到达各自的目标位置。如果可以,求出所需的最短时间(秒数)。

输入格式
第一行包含两个整数 NN1N10001 \le N \le 1000)和 LL1L1091 \le L \le 10^9),分别表示蚂蚁的数量和位置的总数。
第二行包含 NN 个互不相同的整数 A1,A2,,ANA_1, A_2, \dots, A_N1AiL1 \le A_i \le L),表示每只蚂蚁的初始位置。
第三行包含 NN 个互不相同的整数 B1,B2,,BNB_1, B_2, \dots, B_N1BiL1 \le B_i \le L),表示每只蚂蚁的目标位置。

输出格式
输出一行,包含一个整数,表示所有蚂蚁到达目标位置所需的最短时间。如果无论如何都无法全部到达目标位置,则输出星号 *

样例展示与解释

样例 1
输入:

1
2
3
2 2
2 1
2 1

输出:

1
0

样例 1 解释:两只蚂蚁初始就已经在各自的目标位置上,因此需要 00 秒。

样例 2
输入:

1
2
3
2 2
1 2
2 1

输出:

1
1

样例 2 解释:两只蚂蚁可以同时顺时针(或同时逆时针)移动,仅需 11 秒即可到达目标位置。

样例 3
输入:

1
2
3
1 10
1
7

输出:

1
4

样例 4
输入:

1
2
3
3 5
1 3 2
5 2 4

输出:

1
*

样例 5
输入:

1
2
3
3 5
1 3 2
4 2 5

输出:

1
2

样例 5 解释:三只蚂蚁都可以选择逆时针移动,其中第二只蚂蚁需要在中途停留一秒。

思路讲解

image

这道题目,实际上可以 O(n)O(n) 解决(忽略了快排的时间复杂度),至少我们的做法是这个时间复杂度的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
sort(all(lr_global));
for (int i = 0; i < SZ(lr_global); ++i) {
if (lr_global[0].r > lr_global[i].r) {
lr_global[i].r += L;
}
}
auto check = [&]() -> bool {
for (int i = 1; i < N; ++i) {
if (lr_global[i].l == lr_global[i - 1].l) {
return false;
}
}
for (int i = 1; i < N; ++i) {
if (lr_global[i].r <= lr_global[i - 1].r) {
return false;
}
}
return true;
};
if (!check()) {
cout << "*\n";
return;
}

核心代码就这一段,只能说化曲为直 yyds。

1
2
3
4
5
6
7
for (ll shift: {-1, 0, 1}) {
ll ans = 0;
for (auto [l,r]: lr_global) {
ans = max(abs(l + L * shift - r), ans);
}
ans_global = min(ans_global, ans);
}

为什么这个代码对呢?其实在化曲为直下,一切都非常简单。

说白了,我们只要 l 的相对位置不变,r 的相对位置不变,那么就一定有解,是不是?

那么,我们知道,一个点,他切换方向,其实就是 l 在化曲为直的线段上,平移了 Len 位如果其他点不也平移的 L 位的话,这个一定会导致错误的发生(即 l 的相对位置发生变化)!

那么我们就知道了,要切换方向,要么一起切换,要么一起不切换

当然,你会说,这很奇怪啊,明明这个有些例子是有些点逆时针,有些点顺时针啊?其实,这个是因为为了符合我们的第一个条件,就是起始点和结束点必须都保持升序的条件,在保持这个条件的情况下,其实方向的变化是一起的。

AC代码

AC
http://codeforces.com/gym/106416/submission/368041079

心路历程(WA,TLE,MLE……)