打卡信奥刷题(2004)用C++实现信奥 P10848 [EGOI 2024] Circle Passing / 传球游戏

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 2N1 的编号。更具体地,对于每个 0 ≤ i < 2 N − 1 0 \le i < 2N - 1 0i<2N1,学生 i i i i + 1 i + 1 i+1 站在一起。此外,学生 0 0 0 2 N − 1 2N - 1 2N1 也站在一起。

由于老师希望每个人都能结识新同学,所以最好的朋友必须尽可能远离彼此,即相对而站。也就是说,形成第 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 0ki<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,,kM1,其中 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 2N5×108 1 ≤ M ≤ 5 × 1 0 5 1\le M\le 5\times 10^5 1M5×105 M ≤ N M\le N MN 1 ≤ Q ≤ 2 × 1 0 4 1\le Q\le 2\times 10^4 1Q2×104 0 ≤ k 0 < k 1 < ⋯ < k M − 1 < N 0\le k_0<k_1<\cdots<k_{M-1}<N 0k0<k1<<kM1<N 0 ≤ x i , y i < 2 N 0\le x_i,y_i < 2N 0xi,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,Q1000
  • 子任务三( 22 22 22 分): N ≤ 1 0 7 N\le 10^7 N107 M , Q ≤ 1000 M,Q\le 1000 M,Q1000
  • 子任务四( 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考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值