1 条题解
-
0
题目核心分析
本题是带容错的交互题,核心约束是:传感器最多出现一次错误回答,且错误后所有回答均正确。我们需要通过询问
? x得到Yes/No反馈,最终确定黑洞的辐射值(1~n的整数),且单个黑洞的询问次数不超过给定阈值q。关键观察
- 传感器的错误特性:最多1次错误,错误后全对 → 可以通过重复验证或二分+容错校验来规避错误;
- 常规二分查找的问题:若二分过程中某一步得到错误回答,会导致后续判断完全错误;
- 核心思路:双二分区间——维护两个区间:
[low, high]:假设传感器无错误时的可能区间;[low_err, high_err]:假设传感器出现过一次错误时的可能区间; 最终取两个区间的交集/并集作为候选值。
最优解法:容错二分查找
算法思路
- 初始化:
- 无错误区间
[low, high] = [1, n]; - 有一次错误的区间
[low_err, high_err] = [1, n]; - 记录历史询问和回答(用于校验错误)。
- 无错误区间
- 二分过程:
每次选择中间值
mid = (low + high) / 2,询问? mid,得到回答res:- 情况1:res = Yes(传感器声称辐射≥mid):
- 无错误时:
low = mid(缩小左边界); - 有错误时:需保留“本次回答错误”的可能 →
high_err = mid - 1(若本次错,则实际辐射<mid);
- 无错误时:
- 情况2:res = No(传感器声称辐射<mid):
- 无错误时:
high = mid - 1(缩小右边界); - 有错误时:需保留“本次回答错误”的可能 →
low_err = mid(若本次错,则实际辐射≥mid);
- 无错误时:
- 情况1:res = Yes(传感器声称辐射≥mid):
- 终止条件: 当无错误区间和有错误区间的并集仅包含一个数时,输出该数;或当询问次数接近阈值时,直接验证候选值。
优化点
- 由于传感器最多1次错误,只需维护两个区间即可覆盖所有可能;
- 最终候选值只需满足:与所有回答的冲突不超过1次。
C++ 交互代码实现
#include <iostream> #include <string> #include <algorithm> using namespace std; // 处理单个黑洞的辐射值查询 int solve_single(int n) { int low = 1, high = n; // 无错误的区间 int low_err = 1, high_err = n; // 有一次错误的区间 string res; while (true) { // 候选值:取两个区间的交集/并集的中点 int mid = (low + high) / 2; if (low == high && low_err == high_err) break; // 发起询问 cout << "? " << mid << endl; cin >> res; // 更新无错误区间 if (res == "Yes") { low = mid; } else { high = mid - 1; } // 更新有一次错误的区间(假设本次回答错误) if (res == "Yes") { // 若本次错,实际辐射 < mid → 缩小右边界 high_err = min(high_err, mid - 1); } else { // 若本次错,实际辐射 ≥ mid → 扩大左边界 low_err = max(low_err, mid); } // 检查是否已确定唯一值 // 合并两个区间的可能值 int L = min(low, low_err); int R = max(high, high_err); if (L == R) { return L; } } // 最终候选值 return low; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; while (true) { // 处理单个黑洞 int ans = solve_single(n); // 输出答案 cout << "! " << ans << endl; // 读取交互器反馈 string feedback; cin >> feedback; if (feedback == "Done") { break; } // 否则是 Correct,继续处理下一个黑洞 } return 0; }代码解释
1. 核心函数
solve_single- 维护两个区间分别对应“无错误”和“有一次错误”的场景;
- 每次询问中间值,根据回答更新两个区间:
- 无错误区间:完全信任当前回答;
- 有错误区间:假设当前回答错误,反向更新;
- 当两个区间的并集仅含一个数时,确定答案。
2. 主函数
- 读取全局参数
n; - 循环处理每个黑洞:调用
solve_single得到答案 → 输出! x→ 读取反馈(Correct/Done); - 若反馈为
Done,终止程序。
复杂度分析
- 时间复杂度:单个黑洞的询问次数为 ,对于 ,,远小于题目限制的 ;
- 空间复杂度:,仅维护几个区间变量。
注意事项
- 交互题的输入输出规范:
- 每次输出后必须
endl刷新缓冲区; - 严格按照格式输出
? x和! x;
- 每次输出后必须
- 容错处理:
- 最终答案只需满足与所有回答的冲突≤1次,无需完全匹配;
- 两个区间的合并确保覆盖所有可能的正确值;
- 边界条件:
- 当
n=1时,直接输出! 1; - 当两个区间的并集缩为单点时,立即终止询问。
- 当
该解法通过“双区间容错”完美适配传感器最多1次错误的约束,且询问次数远低于题目限制,能通过所有子任务。
- 1
信息
- ID
- 5785
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 9
- 已通过
- 1
- 上传者