#P15667. [Bulgarian2024训练营]魔术

    ID: 14879 通信题 400~1000ms 256MiB 尝试: 6 已通过: 1 难度: 9 上传者: 标签>算法基础构造组合数学数学CF2800

[Bulgarian2024训练营]魔术

题目描述

魔术师 Harry 设计了一个新的纸牌魔术,需要两位助手配合完成。

一副牌中共有 2N+12N+1 张牌,编号为 0,1,2,,2N0,1,2,\ldots,2N。首先从观众中请出一人,观众选择其中一张牌并将其拿走。随后观众把剩余的 2N2N 张牌分成两堆,每堆 NN 张:第一堆交给第一位助手,第二堆交给第二位助手。

第一位助手会从自己拿到的 NN 张牌中依次展示两张牌,也就是说她展示的是一个有序二元组。第二位助手同样从自己拿到的 NN 张牌中依次展示两张牌。两位助手在魔术开始后不能与 Harry 或另一位助手通信。

Harry 只能根据两位助手展示的四张牌以及展示顺序,猜出观众拿走的那张牌。

你的任务是编写程序,分别扮演第一位助手、第二位助手和 Harry,使得 Harry 总能猜出被拿走的牌。

实现要求

你需要实现以下三个函数:

pair<int, int> assistant1(vector<int>& cards);
pair<int, int> assistant2(vector<int>& cards);
int magician(int N, pair<int, int> chosen1, pair<int, int> chosen2);

对于每个测试用例,评测程序会依次调用:

  1. assistant1
  2. assistant2
  3. magician

为了保证三者不能通过全局变量等方式共享信息,在同一个测试用例中,这三个函数会在你的程序的不同运行实例中被调用。

assistant1

pair<int, int> assistant1(vector<int>& cards);

参数 cards 为第一位助手拿到的 NN 张牌的编号。函数需要返回一个有序二元组,表示她展示给 Harry 的两张牌。

返回的两张牌必须都来自 cards,且编号不同。

assistant2

pair<int, int> assistant2(vector<int>& cards);

含义与 assistant1 类似,只是参数为第二位助手拿到的 NN 张牌。

返回的两张牌必须都来自 cards,且编号不同。

magician

int magician(int N, pair<int, int> chosen1, pair<int, int> chosen2);

参数 N 为每位助手手中的牌数,chosen1chosen2 分别为两位助手展示的有序二元组。函数需要返回观众拿走的那张牌的编号。

你的程序可以包含其他函数和全局变量,但不能包含 main 函数,也不能读入标准输入或输出到标准输出。

数据范围

  • 1T600001 \le T \le 60000
  • 6N13000006 \le N \le 1300000
  • 所有测试用例中 NN 的总和满足 N1300000\sum N \le 1300000

子任务

子任务 分值 NN TT N\sum N 其他限制
1 29 =6=6 15000\le 15000 130000\le 130000
2 19 30\le 30
3 30 500\le 500 每个测试中至多 10 个测试用例满足 N>50N>50
4 22 1300000\le 1300000 60000\le 60000 1300000\le 1300000

只有通过某个子任务的全部测试,才能获得该子任务分数。

样例交互

样例中只有一个测试用例,即 T=1,N=6T=1,N=6

assistant1({6, 1, 2, 5, 7, 10})
return {1, 2}

assistant2({3, 0, 4, 9, 12, 8})
return {4, 3}

magician(6, {1, 2}, {4, 3})
return 11

本地测试说明

官方提供 Lgrader.cpp 和示例文件 magic.cpp。将它们放在同一目录下编译后,可以用标准输入进行本地测试。

本地测试程序的输入格式为:

第一行一个整数 TT,表示测试用例数。

对于每个测试用例:

  • 第一行一个整数 NN
  • 第二行 NN 个互不相同的整数,表示第一位助手拿到的牌;
  • 第三行 NN 个互不相同的整数,表示第二位助手拿到的牌。

若某个测试用例失败,本地评测器会输出相应错误信息;若成功,会输出 Correctly guessed card k.,其中 kk 为被猜出的牌。