
前言#
本篇题解适合刚学字符串 ↗和模拟 ↗的同学阅读,语言浅显易懂。谁让作者是个蒟蒻呢。
题目分析#
核心条件:
- 第一个非空格字符必须是井号
#。 - 井号后面必须紧跟着至少一个空格且不能有多个井号相连(如
##)。 - 在井号后面的空格后必须有长度不为 的句子。
思路引导#
:::warning[提问] 如何输入一行含空格的字符串? :::
:::success[成功]
使用 string 类型自带的 getline() 。
:::
:::success[提问]
如何判断字符串是否为一级标题?
:::
:::success[成功] 联系我们刚分析完的核心条件,可以进行模拟。具体如下:
-
首先,假设读入的字符串 不是一级标题, 为 false 。再将 从头到尾扫一遍。
- 如果 是空格,直接跳过。
- 否则如果 为 true ,说明已经满足核心条件中的 1、2 点,且现在 不为空格,也满足第 3 点,计数器 。
- 否则如果 是非
#字符, 必定不是一级标题,跳出循环。 - 否则如果 是
#字符且满足核心条件中的 1、2 点, 为 true 。 - 否则 必定不是一级标题,跳出循环。 :::
完整代码#
#include<bits/stdc++.h>
using namespace std;
int n,pos,cnt; // cnt用于计数符合条件的标题
bool flag; // 标记是否满足标题的前置条件
string s;
int main() {
cin>>n;
cin.ignore(); // 忽略n后面的换行符
while(n--) {
getline(cin,s); // 读取一整行文本
flag=false; // 初始化标记
for(int i=0; i<s.size(); ++i) {
if(s[i]!=' ') { // 遇到非空格字符
if(flag){ // 如果已标记为满足前置条件
cnt++; // 计数加1
break; // 跳出循环,无需继续检查
}
if(s[i]!='#') { // 非#字符,不是标题
break;
}
// 检查是否为单个#且后面跟着空格
if(s[i]=='#'&&(i==0||s[i-1]!='#')&&s[i+1]==' '&&i+1<s.size()) {
pos=i+1;
flag=true; // 标记为满足前置条件
}
if(!flag){ // 如果不满足前置条件
break; // 跳出循环
}
}
}
}
cout<<cnt; // 输出结果
return 0;
}cpp