循环迭代中cin语句被跳过问题求助(CodeChef DIET题)
解决CodeChef DIET题中的输入读取问题
嘿,我看了你的代码和遇到的问题,其实问题出在两个地方——一个是导致你第二次迭代cin被“跳过”的核心原因,另一个是潜在的宏定义bug,咱们一个个说:
核心问题:未处理残留输入导致后续读取异常
当第一个测试用例中,某一天的current + x < diet时,你会输出NO i+1然后break跳出循环。但这时候,这个测试用例剩下的那些天的x值还留在输入缓冲区里!比如假设第一个测试用例是5天,你在第2天就break了,那剩下3个x值还在缓冲区里。当下一个测试用例执行cin>>days>>diet时,它会直接读取这些残留的x值,而不是你期望的新测试用例的天数和饮食量,这就看起来像是cin被跳过了。
如果这些残留输入和days/diet的类型不匹配,cin还会进入失败状态,这时候即使你用了cin.clear()和cin.ignore(),位置不对也没用。
次要问题:宏定义的笔误
你定义的REP2宏里,循环条件写的是i < limit2,但循环变量明明是j,这明显是手滑写错了,应该改成j < limit2。虽然你当前代码里没用到这个宏,但之后用到的话会直接导致逻辑错误,先修复掉比较好。
解决方案
1. 处理残留输入
当你在某个测试用例中提前break(输出NO之后),需要把该测试用例剩下的所有输入从缓冲区里清除掉,这样下一个测试用例才能正常读取新输入。这里有两种稳妥的方式:
方式一:循环读取剩余的x值
直接把当前测试用例剩下天数的x值读完,清空缓冲区:
if(current < diet){ cout<<"NO "<<i+1; res = false; // 读取剩下的天数对应的x,清除缓冲区 for(int k = i+1; k < days; k++){ int temp; cin>>temp; } break; }
方式二:忽略整行输入
如果输入是每行一个数据的格式,可以用numeric_limits忽略到换行符(需要包含<limits>头文件):
#include <limits> // 新增头文件 // ... if(current < diet){ cout<<"NO "<<i+1; res = false; cin.clear(); // 重置cin的失败状态(防止之前读取出错) cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略到换行符,清空当前行残留 break; }
2. 修复宏定义
把REP2的宏改成正确的:
#define REP2(limit2) for(int j = 0; j < limit2; j++)
修改后的完整代码
#include <iostream> #include <limits> // 新增头文件 using namespace std; #define REP(limit) for(int i = 0; i < limit; i++) #define REP2(limit2) for(int j = 0; j < limit2; j++) // 修复宏定义 int main() { int testcases; cin>>testcases; while(testcases--){ int days, diet, current = 0; cin>>days>>diet; bool res = true; REP(days){ int x; cin>>x; cout<<" ss "; current += x; if(current < diet){ cout<<"NO "<<i+1; res = false; // 清除当前测试用例的残留输入 cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); break; } current -= diet; } if(res == true){ cout<<"YES"; } // 每个测试用例结束后输出换行,避免输出混乱 cout<<endl; } return 0; }
额外小建议
- 记得包含必要的头文件,比如
limits用于处理输入缓冲区的忽略操作; - 每个测试用例结束后输出换行,这样不同测试用例的输出不会混在一起,也更符合题目的输出格式要求。
内容的提问来源于stack exchange,提问作者jrseinc
相关产品推荐
相关产品推荐

