Binary Search算法调试求助:Codeforces题目测试点2始终失败
Codeforces二分猜数题测试点2失败问题分析
题目回顾
裁判持有1到n之间的整数x,你需要通过查询猜出它:
- 每次查询输入1到n的整数,输出后需刷新输出流
- 系统响应:
- "<":x < 查询数
- ">=":x >= 查询数
- 猜出后输出"! x"并终止,最多允许25次查询(不含输出答案操作)
你的代码问题分析
#include <iostream> using namespace std; int main() { int n; string s; int k=0; cin>>n; int min=1,max=n; int a; while(k==0) { if(max==min+1) { cout<<"! "<<min; k=1; break; } a=(min+max)/2; cout<<a<<endl; cin>>s; if(s==">=") min=a; else max=a; } }
主要问题如下:
- 边界逻辑错误:当范围缩小到
max = min+1时,直接输出min完全忽略了x等于max的情况,这会直接导致答案错误。 - 未处理n=1的特殊情况:当n=1时,
min和max都是1,循环内的max==min+1条件不成立,会进入循环查询1,之后陷入无限循环(因为min和max始终为1)。 - 二分取整导致的死循环风险:使用
a=(min+max)/2向下取整,当min和max相差1时,若x是max,查询min会得到>=响应,此时min保持不变,循环无法终止(虽然你加了max==min+1的判断,但这个判断本身逻辑错误)。
修正后的代码
#include <iostream> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; int low = 1, high = n; while (low < high) { // 向上取整,避免死循环,同时防止整数溢出 int mid = low + (high - low + 1) / 2; cout << mid << '\n'; cout.flush(); // 显式刷新输出流,确保系统收到查询 string resp; cin >> resp; if (resp == ">=") { low = mid; } else { high = mid - 1; } } cout << "! " << low << '\n'; cout.flush(); return 0; }
修正点说明:
- 使用
low + (high - low + 1)/2计算mid,既避免整数溢出又实现向上取整,彻底防止死循环 - 循环条件改为
low < high,当循环结束时low == high即为答案,无需额外判断 - 显式调用
cout.flush()确保输出流被刷新,严格符合题目要求 - 自动处理所有边界情况(包括n=1)
- 加入
ios::sync_with_stdio(false); cin.tie(nullptr);加速输入输出,避免超时风险
内容的提问来源于stack exchange,提问作者Jovan8
相关产品推荐
相关产品推荐

