#P17274. [eJOI 2026] Elevator

    ID: 19751 远端评测题 10000ms 64MiB 尝试: 0 已通过: 0 显示难度NOI/NOI+/CTS 上传者: 标签>交互题Special JudgeeJOI(欧洲)2026通信题

[eJOI 2026] Elevator

题目描述

这是一道通信题。

一栋建筑的楼层编号为 00 到 NN。第 00 层是地面层,第 NN 层上方是屋顶。因此,包括屋顶在内,建筑共有 N+2N+2 个层面。

每个满足 0≤f≤N0\le f\le N 的楼层 ff 都恰好住着一名居民,并且有一个只有该居民知道的秘密整数 vfv_f,其中 0≤vf≤30\le v_f\le 3。Karlsson 住在屋顶。他的目标是确定 v0,v1,…,vNv_0,v_1,\ldots,v_N 中尽可能多的值,而所有居民都会合作,使他能够恢复的值尽可能多。

居民按照以下方式使用建筑内的电梯进行通信。

电梯从第 00 层出发,并且只向上运行。电梯内有编号为 11 到 NN 的按钮。最初没有按钮被按下;一个按钮一旦被按下,就会永久保持按下状态。如果 f=0f=0,或者第 ff 层的按钮已在此前某次停靠时被按下,电梯就会在第 ff 层停靠并开门。电梯访问完按钮被按下的最高楼层后,会直接前往屋顶,不再停靠其他楼层;如果始终没有按钮被按下,则从第 00 层直接前往屋顶。

当电梯停在第 ff 层时,会依次发生以下事情:

  1. 该层居民看到当前所有已按下按钮的完整集合。
  2. 仅根据这些信息和 vfv_f,居民可以从尚未按下且对应楼层严格高于 ff 的按钮中任选一个子集并按下。
  3. 电梯前往更高楼层中按钮已按下的最低楼层;如果按钮已按下的楼层都已访问,则前往屋顶。

如果电梯没有在某层停靠,该层居民就不能按下任何按钮。

电梯到达屋顶时,Karlsson 只能看到最终被按下的按钮集合。他尝试从这些信息中恢复 v0,v1,…,vNv_0,v_1,\ldots,v_N 中尽可能多的值。

vv 的所有值在程序开始前已经固定,在整个过程中不会改变。

实现细节

共有 TT 个测试用例。你需要提交一个文件,实现以下两个函数。

std::vector<int> press_buttons(int subtask, int N,
                               int f, int v, std::vector<int> p)
  • subtask:本次调用所属的子任务编号,满足 0≤subtask≤40\le\texttt{subtask}\le 4;
  • NN:最后一个楼层的编号;
  • ff:当前楼层,满足 0≤f≤N0\le f\le N;
  • vv:第 ff 层上的值 vfv_f;
  • pp:当前已按下的按钮,按递增顺序给出。

电梯在第 ff 层开门时会调用该函数,即 f=0f=0 或第 ff 层按钮已在此前某次停靠时被按下。若电梯没有在某层停靠,则不会为该层调用此函数。

返回值是需要新按下的按钮列表,顺序不限。每个返回的按钮 xx 必须满足:

  • f<x≤Nf<x\le N;
  • xx 不在 pp 中,并且在返回数组中恰好出现一次。
std::vector<int> answer(int subtask, int N, std::vector<int> p)
  • subtask:本次调用所属的子任务编号,满足 0≤subtask≤40\le\texttt{subtask}\le 4;
  • NN:最后一个楼层的编号;
  • pp:最终已按下的按钮集合,按递增顺序给出。

电梯到达屋顶时,每个测试用例恰好调用一次该函数。

返回数组的长度必须为 N+1N+1。如果 Karlsson 能恢复 viv_i,则其第 ii 个元素应等于 viv_i;否则应为 −1-1。

重要: 建筑内的人不能通过按钮之外的任何方式通信。你的程序会作为 N+2N+2 个相互独立的进程运行:每个楼层一个进程,屋顶一个进程。每个楼层进程最多收到 TT 次 press_buttons 调用,屋顶进程恰好收到 TT 次 answer 调用。因此,程序不得假设存在任何共享状态,例如全局变量。每个进程分别拥有 64 MiB 内存;总计至多 (N+1)T(N+1)T 次 press_buttons 调用和恰好 TT 次 answer 调用都必须在 10 秒内完成。

输入格式

样例评测器会在一次运行中完成所有测试用例的全部函数调用。

输入格式:

  • 第 11 行:测试用例数 TT、最后一个楼层编号 NN 和子任务编号 SS;
  • 第 1+i1+i 行:测试用例 ii 的 N+1N+1 个整数 v0,v1,…,vNv_0,v_1,\ldots,v_N。

输出格式

输出格式:

  • 第 ii 行:测试用例 ii 中正确恢复的值的数量;
  • 第 T+1T+1 行:最终得分。

如需更详细的反馈,将评测器第一行的宏 DETAILED 从 false 改为 true。如需让评测器自动生成 vfv_f,将第二行的宏 AUTO_GENERATE 从 false 改为 true。

提示

样例

样例包含一个测试用例,其楼层值为:

1 1 0 1 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0 1 1 1
1 0 1 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 1 1 1 0 1 1 1 1 0 1 1

一次可能的交互如下:

选手程序 评测程序
press_buttons(0, 60, 0, 1, {})
return {2}
press_buttons(0, 60, 2, 0, {2})
return {13, 42}
press_buttons(0, 60, 13, 0, {2, 13, 42})
return {}
press_buttons(0, 60, 42, 1, {2, 13, 42})
return {}
answer(0, 60, {2, 13, 42})
return {1, -1, 0, -1, -1, ..., -1}

这次交互正确恢复了下标 00 和 22 处的值。其他返回值均为 −1-1,因为 Karlsson 未能恢复它们。

限制

  • N=60N=60
  • T≤10 000T\le 10\,000
  • 对每个 0≤i≤N0\le i\le N,均有 0≤vi≤30\le v_i\le 3

子任务

子任务 分值 附加限制 获得满分所需恢复的楼层数
0 样例。 -
1 15 0≤vi≤10\le v_i\le 1;v0=vN=1v_0=v_N=1;对每个 0≤i<N0\le i<N,若 vi=0v_i=0,则 vi+1=1v_{i+1}=1 60
2 35 0≤vi≤10\le v_i\le 1 40
3 15 0≤vi≤20\le v_i\le 2 30
4 35 0≤vi≤30\le v_i\le 3 25

评分

如果程序在某个子任务的任何测试用例中返回了错误恢复值或执行了非法操作,例如返回长度错误的 vector,则该子任务得 00 分。

对于一个测试用例,恢复数量是返回值不等于 −1-1 的位置数。令 KK 为该子任务所有测试用例中恢复数量的最小值。每个子任务只有一个测试,其中包含至多 10 00010\,000 个测试用例。得分按下表计算:

子任务 KK 的范围 得分
0 - 00
1 K<60K<60 0.25K0.25K
K≥60K\ge 60 1515
2 K<30K<30 0.5K0.5K
30≤K<4030\le K<40 2K−452K-45
K≥40K\ge 40 3535
3 K<30K<30 0.5K0.5K
K≥30K\ge 30 1515
4 K<20K<20 0.7K0.7K
20≤K<2520\le K<25 4K−664K-66
K≥25K\ge 25 3535