#include <iostream>
#include <string>
using namespace std;
int main() {
int len, maxlen;
string s, ss;
maxlen = 0;
do {
cin >> ss;
len = ss.length();
if (ss[0] == '#')
break;
if (len > maxlen) {
s = ss;
maxlen = len;
}
} while (true);
cout << s << endl;
return 0;
} 输入: I am a citizen of China \#
输出:_________
看到循环里只有 maxlen 和 s 两个变量在变,而且每次更新 maxlen 都顺手把 s 赋值了,这题其实就是考你:程序到底在读哪个串、什么时候停、遇到长度相同的串会保留哪个。顺着输入逐行模拟就出来了。
最容易栽跟头的是把 do-while 当成 while,导致少读一行;还有少数人会盯着'China'后面那个空格把'China '当成一个串,其实 cin 会自动跳过空白,'China '根本进不来;另外有人以为遇到长度相同会更新,结果把'citizen'换成了'China',但题目里 maxlen 只在 len > maxlen 时才更新,等于时 s 不动,所以答案只能是'citizen'。
这题考的是 C++ 里 std::string 的基本用法,特别是 cin 对字符串的读取规则:遇到空白(空格、换行、制表符)就停止,不会把带空格的整行读进来。同时考的是循环里变量的更新逻辑——只有当新串长度严格大于当前记录的最长长度时,才会把 s 替换成新串。这两个点结合起来,就是典型的“读多行、取最长”的模拟题。
NOIP 初赛喜欢用一段很短的代码来测你是否真正理解语言细节,而不是背模板。这道题故意把循环写成 do-while,而且停止条件放在循环体内部(ss[0]=='#'),这样你如果只扫一眼代码,很容易忽略先读再判断的顺序,或者误以为遇到'#'就立刻跳出,忘了'#'本身也要被读进去。另外,命题人还埋了一个“长度相同不更新”的坑:输入里'China'长度是5,'citizen'长度也是7,中间并没有长度相等的情况,但很多人会下意识觉得“遇到更长的就换,遇到一样长的也换”,结果把答案搞错。这些都是命题人精心设计的“挖坑点”。