原题链接:https://www.acwing.com/problem/content/description/3292/
# include <iostream>
# include <vector>
# define BLANK 0 //空行
# define PARA 1 //文本
# define PROJ 2 //项目
# define PROJ_NEXT 3
using namespace std;
const int N = 10 + 20 * 1024 * 1024;
char str[N];
vector<string> strs;
int w, ans = -1;
int cur = -1, pre = -1; // 存上一个处理的行的类型
// 判断空行
bool is_blank(string& s) {
for (auto c: s)
if (c != ' ') return false;
return true;
}
// 判断str的类型
int get_type(string& str) {
if (is_blank(str)) return BLANK;
if (str.size() >= 2 && str[0] == '*' && str[1] == ' ') return PROJ;
if ((pre == PROJ || pre == PROJ_NEXT) && str.size() >= 2 && str[0] == ' ' && str[1] == ' ') return PROJ_NEXT;
// 前三种都不是的话,就是文本了
return PARA;
}
// 统计行数 传入一个string,w。返回这个string占的行数
int wc(string& s, int w) {
int res = 0;
for (int i = 0; i < s.size(); i ++ ) {
// 开头的空格自动删除
if (s[i] == ' ') continue;
// 统计一行
int j = i + 1;
while (j < s.size() && j - i + 1 <= w) j ++ ;
res ++ ;
i = j - 1;
}
return max(res, 1);
}
// 去掉str前面和后边的连续空格
string trim(string s)
{
int i = 0, j = s.size() - 1;
while (i <= j && s[i] == ' ') i ++ ;
while (i <= j && s[j] == ' ') j -- ;
if (i > j) return "";
return s.substr(i, j - i + 1);
}
// 连行成段
void fix_para(int& i) {
// 与之前的PARA或PROJ隔开
ans ++;
pre = PARA;
string obj = trim(strs[i++]);
while (i < strs.size()) {
int t = get_type(strs[i]);
if (t != PARA) break;
pre = PARA;
// 行与行合并中间+空格
obj += " " + trim(strs[i]);
i ++;
}
// cout << obj << endl;
ans += wc(obj, w);
}
// 处理一个 ·
void fix_proj(int& i) {
if(pre != PROJ && pre != PROJ_NEXT) ans ++; // 若之前是项目则无需换行
pre = PROJ;
//在渲染一个项目前,先把这个项目的各个文本行首的两个空格字符或星号空格字符去掉。
string obj = trim(strs[i ++].substr(2));
while (i < strs.size()) {
int t = get_type(strs[i]);
if (t != PROJ_NEXT) break;
pre = t;
obj += ' ' + trim(strs[i].substr(2));
i ++;
}
// cout << obj << endl;
// w发生变化
ans += wc(obj, w - 3);
}
int main()
{
scanf("%d", &w);
getchar(); // 处理w之后的回车。
while (fgets(str, N, stdin))
{
strs.push_back(str);// 把每一行存到str中,然后放入strs结构体
if (strs.back().back() == '\n') strs.back().pop_back(); // 删除回车
}
int i = 0;
// 遍历每一行的字符串
while (i < strs.size()) {
cur = get_type(strs[i]);
// printf("i=%d, cur=%d\n", i, cur);
if (cur == BLANK) i ++, pre = BLANK;
else if (cur == PARA) fix_para(i);
else if (cur == PROJ) fix_proj(i);
// printf("ans=%d\n",ans);
}
printf("%d", ans);
return 0;
}