题目来源于CCF CSP
思路分析
参考M_theory004的代码思路,自己整理了一下:
这道题看着头大,文字描述比较多。
-
定义一个容器,存入每个项目或者段落的字符串,并且用标志位标识开来。
-
遇到相同项目列表时,第一个标识1,后续的子项目标识为2,这是为后面空行做铺垫,因为每个项目列表与段落或者项目列表与项目列表之间都要有一个空行隔开。
-
每次存入容器的时候,查看紧邻的上一行是空行还是项目或者段落。
- 如果上一行是空行,那么此时存入容器的只能是段落或者新的项目列表;
- 如果上一行是项目,那么若此时输入的字符串开始为两个空行,那么可知为项目的内容时,直接一个空格隔开,然后与上一个项目字符串连接;若此时输入的字符串开始为“* ”,那么可知为子项目,直接放入容器即可。此外,输入就可能是段落,也是直接放入即可。
- 如果上一行是段落,那么此时的输入只有两种可能,若输入是新项目,那么直接存入即可;或者输入是段落的内容,那么接在上一行的字符串后面即可(注意使用一个空格隔开)。
-
最后计算行数,那么直接遍历上面设置的容器,遇到项目列表(1)或者段落时,直接加一,因为需要空行隔开。然后再判断,容器的弹出的元素如果是项目,那么判断是否是空项目,若是,直接加一;否则,按照每行最后空三个空格为准进行计算即可。
代码解析
有参考M_theory004的代码,部分实现进行了优化。
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
/*Delete the leading and trailing spaces*/
string Delete_Space(string str) {
str.erase(0, str.find_first_not_of(' '));
str.erase(str.find_last_not_of(' ') + 1);
return str;
}
int main()
{
ios::sync_with_stdio(false);
int w, ans = 0;
bool flag = false;
string str = "";
vector<pair<string, int>> vec; // 1新项目 ,2 子项目,3段落
cin >> w; //终端宽度
//检查最开始是否是空行
while (getline(cin, str)) {
//检测是否为空行
if (str.size() == count(str.begin(), str.end(), ' '))
flag = true;
//非空行时
else {
//上一行为空行时或者不存在上一行时
if (flag || vec.empty()) {//新项目
if (str.size() >= 2 && str.substr(0, 2) == string("* ")) {
vec.push_back(make_pair(Delete_Space(str.substr(2)), 1));
}
else {//为段落时
vec.push_back(make_pair(Delete_Space(str), 3));
}
flag = false;
}
//上一行非空行
else {//查看上一行标志类型
pair<string, int>& last = vec.back();
//上一行为项目时
if (last.second <= 2) {
//为项目的内容时,直接空格隔开,然后连接
if (str.size() >= 2 && str[0] == ' ' && str[1] == ' ') {
last.first += " ";
last.first += Delete_Space(str.substr(2));
}
//与上一个是同一个项目列表
else if (str.size() >= 2 && str[0] == '*' && str[1] == ' ')
vec.push_back(make_pair(Delete_Space(str.substr(2)), 2));
else//为段落时
vec.push_back(make_pair(Delete_Space(str), 3));
}
else { //上一行为段落时
if (str.size() >= 2 && str[0] == '*' && str[1] == ' ')//新项目
vec.push_back(make_pair(Delete_Space(str.substr(2)), 1));
else { //段落内容
last.first += " ";
last.first += Delete_Space(str);
}
}
}
}
}
for (int i = 0; i < vec.size(); ++i) {
string str = vec[i].first;
//输出中间空行
if (vec[i].second != 2 && i > 0)
ans++;
//为项目时
if (vec[i].second <= 2) {
if (str.size() == 0)//是空行
ans++;
else {//非空行
for (int i = 0; i < str.size(); i += (w - 3)) {
//删去每行开始可能的空格
while (i < str.size() && str[i] == ' ')
i++;
ans++;
}
}
}
else {//为段落时
for (int i = 0; i < str.size(); i += w) {
//删去每行开始可能的空格
while (i < str.size() && str[i] == ' ')
i++;
ans++;
}
}
}
cout << ans << endl;
return 0;
}
测试结果