NOIP 提高组初赛 · NOIP 2015 提高组初赛试题 第 25 题

选择题 · 答案 citizen · 考点:字符数组与字符串处理

← 整套速查表 NOIP 提高组初赛 全部真题

题目

#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 \#

输出:_________

答案:citizen

考点

字符数组与字符串处理 讲解 →字符数组与字符串处理 真题汇总 →

解题思维

看到循环里只有 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,中间并没有长度相等的情况,但很多人会下意识觉得“遇到更长的就换,遇到一样长的也换”,结果把答案搞错。这些都是命题人精心设计的“挖坑点”。

同考点真题

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断