- 题目来源
- 知识点
- 注意点
- 10分
- 20分
- 40分
- 思路
- 代码
- 80
CSP MarkDown渲染器
知识点-
eof() 函数: 按题意需要 !cin.eof() 。 cin 是输入来源, cin.eof() == true 是 cin 中的数据到达了末尾。
-
getline() 函数: 按题意需要 getline(cin, str)。 cin 是输入来源, str 是接受字符的变量名。
-
他俩都不需要头文件。
-
substr的用法
str1 = "I live in China." str2 = str1.substr(2, 4) //str1.substr(pos, len); pos: 下标, len:长度 cout<
- 注释掉 isftream !!!
- 除了有字符的行外, 段落、项目列表间的空行也要算上。
数据特征: 仅包含段落, 每个段落仅包含一行, 每行文本长度不超过w。
解决方案: 记录 非空白行数量(仅含0个或多个空格的行),和行之间的 间距数 (非空白行 - 1)。
#include#include using namespace std; int main() { //ifstream cin("in.txt"); // 一定要记得注释掉 int w; cin>>w; long ans = 0; while ( !cin.eof()) { // 是否到达文件末尾 string str; getline(cin, str); // 获取一整行, 遇到换行符才停 bool flag = false; for (int i = 0; i < str.size(); ++i) { if (str[i] != ' ') { flag = true; break; } } if (flag) { ++ans; // 记录段落数 } } ans += ans - 1; // 答案是 段落数 + 段落数 - 1 cout< 20分 数据特征: 仅包含段落, 每个段落仅包含一行文本, 不保证每行文本长度小于w。
解决方法: 设置一个headTail(hh, tt)函数, 除去 str[hh, tt]字符串的头尾空格。 然后就看代码中的 while循环 吧, 这是最主要的部分。代码:
#include#include using namespace std; string str; // 一行的内容 int h, t; // 去除头尾空格后的字符始末下标 // 除去 str[hh, tt] 头尾 的空格 void headTail(int hh, int tt) { h = hh, t = tt; while (h < str.size() && str[h] == ' ') { ++h; } while (t >= 0 && str[t] == ' ') { --t; } } int main() { ifstream cin("in.txt"); int w; cin>>w; long rowWstr = 0, part = 0; // 有字符的行的行数, 段落、项目数 while ( !cin.eof()) { // 是否到达文件末尾 getline(cin, str); // 一行一行地获取 int oldRWS = rowWstr; // 记录处理前的 rowWstr int hh = 0, tt = str.size() - 1; // 记录当前剩余的str while (true) { headTail(hh, tt); // 除去 str[hh, tt] 头尾的空格 hh = h, tt = t; // 更新后的内容 if (hh <= tt) { // 剩余的str, 除去头尾的空格后还有元素 ++rowWstr; hh = hh + w; } // 没有剩余的元素了 else { break; } } if (rowWstr != oldRWS) { // 这一行不是空白行 ++part; } } long ans = rowWstr + part - 1; cout< 40分 (未成功, 仅纪念)
代码:#include#include using namespace std; string str; // 一行的内容 long long h, t; // 去除头尾空格后的字符始末下标 // 除去 str[hh, tt] 头尾 的空格 void headTail(int hh, int tt) { h = hh, t = tt; while (h < str.size() && str[h] == ' ') { ++h; } while (t >= 0 && str[t] == ' ') { --t; } } int main() { ifstream cin("in.txt"); int w; cin>>w; long long rowWstr = 0, part = 0; // 有字符的行的行数, 段落、项目数 bool isPreText = false; // 前一行是非空白行吗? int preStop = 0; // 前一行的结束的字符的下标 while ( !cin.eof()) { // 是否到达文件末尾 getline(cin, str); // 一行一行地获取文本 //cout< // 前一行是空白行 preStop = 0; } else { // 前一行 非空白行 if (preStop != 0) { preStop += 1; // 需要一个空格 } } bool isCurText = false; // 先默认这一行是空白行 int hh = 0, tt = str.size() - 1; // 记录当前剩余的str while (true) { //cout< //cout<<" <= "< if (preStop == 0) { ++rowWstr; } hh = hh + w - preStop; preStop = hh > tt? tt - h + 1: 0; isCurText = true; } else { //cout<<" >"< // 前一行是空白行, 当前行不是空白行, 代表有一个段落啦 ++part; } isPreText = isCurText; //cout< 数据特征: 仅包含段落。(一个段落中会有多行文本, 要注意同一段落行间文本的衔接)。
思路
解决方案: 如下只满足 40 分的要求 由于实在是改不成40分了,就在网上看其他伙伴的文章,最终完全换了种思路了(更贴合题目中段落第二段的思路。)(大家都要仔细看题ha,题目中给了蛮多的提示了,不要像我一样舍近求远了)。 思路: 1. 先将文本内容全部存起来(我这里用vector代码来存每一个段落(只存非空白行)) 2. 对每一段按中断宽度的大小进行划分(这里也要记得删掉前边的空格) #include#include #include using namespace std; // 判断是不是空白行 bool isEmpty(string &str) { for (long long i = 0; i < str.size(); ++i) { if (str[i] != ' ') { return false; } } return true; } // 除去 str[h, t] 头尾 的空格 void headTail(string &str, long long &h, long long &t) { while (h < str.size() && str[h] == ' ') { ++h; } while (t >= 0 && str[t] == ' ') { --t; } } int main() { ifstream cin("in2.txt"); int w; cin>>w; vector text; bool isPretext = false, isCurtext = false; while ( !cin.eof()) { // 是否到达文件末尾 string str; getline(cin, str); // 一行一行地获取文本 //cout< // str 是空白行 isCurtext = false; } else { isCurtext = true; long long h = 0, t = str.size() - 1; headTail(str, h, t); string newStr = str.substr(h, t - h + 1); if ( !isPretext) { // 前一行是空白行, 当前行不是空白行 //text.emplace_back(""); text.emplace_back(newStr); } else { text[text.size() - 1] += (" " + newStr); } } isPretext = isCurtext; } long long ans = 0; for (long long i = 0; i < text.size(); i++) { //cout<<"i = "<#include #include #include using namespace std; bool isEmpty(string &str) { for (long long i = 0; i < str.size(); ++i) { if (str[i] != ' ') { return false; } } return true; } // 除去 str[hh, tt] 头尾 的空格 void headTail(string &str, long long &h, long long &t) { while (h < str.size() && str[h] == ' ') { ++h; } while (t >= 0 && str[t] == ' ') { --t; } } int main() { //加速了cin速度,否则造成超时 //ios::sync_with_stdio(false); ifstream cin("in3.txt"); int w; cin>>w; // 存储 vector text; int preState = 0, curState = 0; // 0: 空白行, 1:文本, 2:项目头, 3:项目其它文本 while ( !cin.eof()) { // 是否到达文件末尾 string str; getline(cin, str); // 一行一行地获取文本 //cout< // str 是空白行 curState = 0; //cout<<"*empty*"< bool isPara = true; // 避免代码重复 if (str.size() > 1) { // 可能是项目 if (str[0] == '*' && str[1] == ' ') { // 是项目头 // 将项目头加入text中 curState = 2; long long h = 2, t = str.size() - 1; headTail(str, h, t); string newStr = str.substr(h, t - h + 1); if (preState == 2 || preState == 3) { // 前面有项目 newStr = '2' + newStr; } else { // 前面没项目 newStr = '3' + newStr; } text.emplace_back(newStr); isPara = false; //cout<<"*head*"< // 是项目接下来的部分 curState = 3; // 将项目体加入text中 long long h = 2, t = str.size() - 1; headTail(str, h, t); string newStr = str.substr(h, t - h + 1); if (text[text.size() - 1].size() == 1) { // 项目头没有字符 // 不加空格 } else { newStr = (" " + newStr); // 记得加空格 } text[text.size() - 1] += newStr; isPara = false; //cout<<"*body*"< // 是段落 curState = 1; long long h = 0, t = str.size() - 1; headTail(str, h, t); string newStr = str.substr(h, t - h + 1); if ( preState != 1) { // 前一行不是段落, 当前行是段落 text.emplace_back("1" + newStr); // 弄个标记 } else { text[text.size() - 1] += (" " + newStr); } //cout<<"*Para*"< //cout< = h) { headTail(text[i], h, t); if (t >= h) { ++ans; h += (w - 3); } else { break; } } } //preState = curState; //cout<<"i = "<



