P10848 [EGOI 2024] Circle Passing / 传球游戏
题目背景
Day 2 Problem A.
题面译自 EGOI2024 circlepassing。翻译来自于 ChatGPT 并进行人工校对,若有误请联系 rui_er。
题目描述
这是 Anouk 高中的第一天;作为热身活动,她的体育老师让班级玩记忆名字的游戏。班上有 2 N 2N 2N 名学生。他们中的大多数人彼此不认识,但有 M M M 对最好的朋友,他们一起做任何事情。每个学生最多有一个最好的朋友。
老师把所有学生安排成一个圆圈,连续给每个学生分配一个从 0 0 0 到 2 N − 1 2N - 1 2N−1 的编号。更具体地,对于每个 0 ≤ i < 2 N − 1 0 \le i < 2N - 1 0≤i<2N−1,学生 i i i 和 i + 1 i + 1 i+1 站在一起。此外,学生 0 0 0 和 2 N − 1 2N - 1 2N−1 也站在一起。
由于老师希望每个人都能结识新同学,所以最好的朋友必须尽可能远离彼此,即相对而站。也就是说,形成第 i i i 对好朋友的学生分别站在位置 k i k_i ki 和 k i + N k_i + N ki+N,其中 0 ≤ k i < N 0 \le k_i < N 0≤ki<N。
老师选择了两个学生 x x x 和 y y y 并将一个球交给学生 x x x。目标是将球传给学生 y y y,但每个学生只能将球传给另一个他们已经知道名字的学生。当然,最好的朋友彼此知道对方的名字。在老师解释规则期间,每个学生都认识了直接站在他们旁边的两个学生的名字。除此之外,没有人知道其他人的名字。
游戏玩了 Q Q Q 次;每次老师选择两个学生。由于学生们没有注意,他们在游戏过程中不会学到任何新名字。在每场游戏中,从学生 x x x 到学生 y y y 需要的最少传球次数是多少?
输入格式
输入的第一行包含三个整数, N , M N, M N,M 和 Q Q Q,其中 2 N 2N 2N 是 Anouk 班上的学生数, M M M 是最好朋友的对数, Q Q Q 是进行的游戏次数。
第二行包含 M M M 个整数 k 0 , ⋯ , k M − 1 k_0 ,\cdots, k_{M-1} k0,⋯,kM−1,其中 k i k_i ki 描述了第 i i i 对好朋友。对于每个 i i i,最好朋友分别站在位置 k k k 和 k + N k + N k+N。每个学生最多有一个最好的朋友。
接下来的 Q Q Q 行每行包含两个整数, x i x_i xi 和 y i y_i yi,即第 i i i 场游戏中选择的两个学生。
输出格式
输出 Q Q Q 行,第 i i i 行包含一个整数,即第 i i i 场游戏中所需的最少传球次数。
输入输出样例 #1
输入 #1
4 1 5
1
1 4
1 5
1 7
1 2
1 6
输出 #1
2
1
2
1
2
输入输出样例 #2
输入 #2
6 1 3
5
5 7
5 1
5 11
输出 #2
2
3
1
输入输出样例 #3
输入 #3
4 2 4
2 3
0 2
0 3
0 6
0 7
输出 #3
2
2
2
1
输入输出样例 #4
输入 #4
5 2 5
0 4
0 9
1 8
8 3
1 6
3 9
输出 #4
1
3
3
3
2
输入输出样例 #5
输入 #5
500000000 4 3
543234 1234566 2300001 249999999
2334445 123567
6578996 12455726
3 269979899
输出 #5
2210878
5876730
231106567
说明/提示
样例解释
以下两图描述了第一个样例和第四个样例中的排列情况。如果两个学生彼此认识,他们之间就有一条边连接。
在第一个样例的第一个游戏中,球被传给学生 1 1 1。学生 1 1 1 将球传给他们的好朋友学生 5 5 5。球在学生 5 5 5 传给学生 4 4 4 后到达学生 4 4 4,总共需要两次传球。
数据范围
对于全部数据, 2 ≤ N ≤ 5 × 1 0 8 2\le N\le 5\times 10^8 2≤N≤5×108, 1 ≤ M ≤ 5 × 1 0 5 1\le M\le 5\times 10^5 1≤M≤5×105 且 M ≤ N M\le N M≤N, 1 ≤ Q ≤ 2 × 1 0 4 1\le Q\le 2\times 10^4 1≤Q≤2×104, 0 ≤ k 0 < k 1 < ⋯ < k M − 1 < N 0\le k_0<k_1<\cdots<k_{M-1}<N 0≤k0<k1<⋯<kM−1<N, 0 ≤ x i , y i < 2 N 0\le x_i,y_i < 2N 0≤xi,yi<2N 且 x i ≠ y i x_i\ne y_i xi=yi。
- 子任务一( 14 14 14 分): M = 1 M=1 M=1 且 x i = k 0 x_i=k_0 xi=k0。换句话说,仅有一对最好的朋友,且在每局游戏中,最开始有球的人有一个最好的朋友。
- 子任务二( 20 20 20 分): N , M , Q ≤ 1000 N,M,Q\le 1000 N,M,Q≤1000。
- 子任务三( 22 22 22 分): N ≤ 1 0 7 N\le 10^7 N≤107 且 M , Q ≤ 1000 M,Q\le 1000 M,Q≤1000。
- 子任务四( 17 17 17 分): x i = 0 x_i=0 xi=0。
- 子任务五( 27 27 27 分):无特殊限制。
注:部分测试点在 EGOI 中被放在多个子任务中。为节省评测资源及整理数据的工作量,这些测试点被放在包含它的所有子任务中编号最小的一个。这可能导致一份代码得到比预期更高的分数,但是无法过题。
C++实现
#include<iostream>
#include<algorithm>
#include<numeric>
#include<set>
using namespace std;
const int _ = 5e5+50;
int n,m,q,ki,xi,yi;
set<int> s;
int dist(int u,int v){// 两个点之间直接距离
if(u>v) swap(u,v); // u<= v
return min(v-u, 2*n-(v-u));
}
void query(int x,int y){
int ans = dist(x,y);
if( m != 0){
auto rf = s.lower_bound(x);
if(rf == s.end()) // x is larger than any
rf = s.begin();
ans = min(ans, 1+dist(*rf, x)+dist((*rf+n)%(2*n),y));
if(rf == s.begin())
rf = s.end();
rf--;
ans = min(ans, 1+dist(*rf, x)+dist((*rf+n)%(2*n),y));
}
cout<<ans<<endl;
}
int main(){
ios::sync_with_stdio(0),
cin.tie(0),cout.tie(0);
cin>>n>>m>> q;
for(int i =1; i<=m ;i++)
cin>> ki, s.insert(ki), s.insert(ki + n);
while( q--)
cin>> xi>> yi, query(xi, yi);
}
后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容