#L5321. 「EGOI2025」黑暗乘车
「EGOI2025」黑暗乘车
题目描述
题目译自 European Girls' Olympiad in Informatics 2025 Day1 T2. Dark Ride
黑暗之旅有 个房间(编号 到 )和 个开关(编号 到 ),开关 控制房间 ( 是隐藏的排列,未知)。目标是找到两个开关 和 ,使得它们分别控制房间 和 (顺序不限),规则与交互方式如下:
- 初始状态:每次旅程前所有灯光关闭。
- 开关设置:选择部分开关打开(输出由 0/1 组成的字符串,1 表示打开),启动旅程。
- 尖叫次数:旅程按房间 顺序进行,相邻房间明暗状态变化时产生 1 次尖叫,交互器返回尖叫次数 。
- 限制:最多发起 30 次旅程,最终输出正确的 和 。
交互方式
- 输入初始信息:首先读取整数 (房间与开关数量)。
- 发起旅程:输出一行
? S( 是长度为 的 0/1 字符串),刷新输出后,读取交互器返回的尖叫次数 。 - 提交答案:确定结果后,输出一行
! A B( 和 是控制房间 和 的开关),刷新输出后程序退出。 - 关键说明:交互器非自适应,隐藏排列 在交互开始前固定。
样例解析
样例 1
交互流程
| 交互器输出(输入到你的程序) | 你的程序输出(发送到交互器) | 说明 |
|---|---|---|
? 10001 |
打开开关 0 和 4,对应控制房间 和 | |
? 10110 |
打开开关 0、2、3,对应控制房间 、、 | |
! 2 4 |
开关 2 控制 ,开关 4 控制 ,答案正确 |
隐藏排列
,首次旅程中亮灯房间为 ,旅程中状态变化为:暗→亮(房间 1→2)、亮→暗(2→3)、暗→亮(3→4),共 3 次尖叫。

样例 2
交互流程
| 交互器输出 | 你的程序输出 | 说明 |
|---|---|---|
? 111 |
打开所有开关,所有房间亮,无状态变化,尖叫次数 0 | |
? 110 |
打开开关 0、1,对应控制房间 、 | |
? 000 |
关闭所有开关,所有房间暗,尖叫次数 0 | |
! 1 0 |
开关 1 控制 ,开关 0 控制 (房间 ),答案正确 |
核心解题思路
1. 关键观察:亮灯房间与尖叫次数的关系
- 设打开的开关对应控制的房间集合为 (亮灯房间),将 按房间编号排序为 。
- 尖叫次数 的计算规则:
- 若 :开头有 1 次(暗→亮,房间 );
- 若 :结尾有 1 次(亮→暗,房间 );
- 中间每两个相邻亮灯房间 和 ():产生 1 次(亮→暗→亮,中间暗房间段导致 1 次变化)。
- 简化公式:(例如,全亮时段数为 1,;仅房间 0 和 亮时,段数为 2,)。
2. 核心策略:二分法定位目标开关
目标是找到控制房间 的开关 和控制房间 的开关 ,利用“单次旅程可验证一组开关是否包含 或 ”的特性,用二分法减少查询次数(30 次足够覆盖 的情况)。
步骤 1:定位控制房间 0 的开关
- 对开关编号 进行二分,每次选择一个区间 的开关打开,发起旅程:
- 若尖叫次数包含“开头亮灯”的特征(如段数变化),说明 在 内,缩小范围到左半区;
- 否则 在右半区,继续二分。
- 重复直至找到唯一的 (仅打开 时,尖叫次数为 1:暗→亮(房间 0)、亮→暗(房间 0→1))。
步骤 2:定位控制房间 的开关
- 同理,二分开关编号,每次打开区间内的开关,结合已找到的 (固定打开 以辅助判断),通过尖叫次数是否包含“结尾亮灯”的特征,定位 。
- 仅打开 时,尖叫次数为 1:暗→亮(房间 前的暗→亮)、亮→暗(无,因房间 是最后一个,故仅 1 次变化)。
3. 优化:减少查询次数
- 每次二分查询可同时验证“是否包含 ”和“是否包含 ”(例如打开一组开关,根据尖叫次数判断是否同时包含两者、仅含其一或都不含),进一步减少查询次数(理论上 2 次二分共需约 次, 时仅需约 30 次)。
数据范围与子任务
| 子任务 | 分值 | 附加限制 |
|---|---|---|
| 1 | 9 | |
| 2 | 15 | |
| 3 | 17 | (开关 0 控制房间 0) |
| 4 | 16 | 为偶数, 且 |
| 5 | 14 | |
| 6 | 29 | 无特殊限制 |