-
题目链接:Markdown渲染器
-
这题写的时候绕晕了,代码转自:热爱Data的直男熙哥,我按自己的习惯改了一点格式加了一些注释
-
题目描述
-
题目分析:
- CSP的第三题真的是很麻烦的模拟,之前字符画那题也是,看题都要看好久,我这里绕晕了没做出来。不过看到 ”热爱Data的直男熙哥“ 的解法,感觉很清晰,所以搬过来了。
- 题目要求的整个处理过程很复杂,一遍遍历完成很容易想乱掉,所以可以把处理过程分成两部分
- 预处理过程:这个过程中,把输入分成三类:段落、列表首项、列表非首项,这个过程中把相同段落/列表项的多行输入拼接起来,打上类别标记后存入vector管理
- 渲染过程:这个过程中,遍历vector中的内容,因为预处理时已经把内容都划分好了,所以思路很清晰。段落和列表间隔时插入空行、段内/列表项内按终端每行容量处理换行
-
因为题目中没有给出输入的行数,需要自行处理。根据提示,我们用
getline(cin,str)
形式输入,通过检测文件末尾来跳出循环。windows中用ctrl+z代表eof,所以debug测试时,在黑框中按下ctrl+z,然后回车,就可以结束输入。 -
满分代码
/* while(getline(cin, str))或者 while(cin >> str)跳出循环的方式: windows下:输入流对象cin输入的结束符在windows下是ctrl+z,所以,按下ctrl+z,然后回车,程序就正常跳出循环了 */ #include <iostream> #include <vector> using namespace std; struct Markdown { int type; string s; }; vector<Markdown> article; //判断是否为空行 bool isspace(string str) { for(int i=0;i<str.length();i++) if(str[i]!=' ') return false; return true; } //去除首尾空格 string standard(string str) { int len = str.length(); int pos1 = 0,pos2 = len-1; while(str[pos1] == ' ') pos1++; while(str[pos2] == ' ') pos2--; str = str.substr(pos1,pos2-pos1+1); return str; } int main() { //加速了cin速度,否则造成超时 ios::sync_with_stdio(false); int n; cin>>n; //通过第一行判断是什么文本 string str; while(getline(cin,str)) { if(!isspace(str)) //跳过空行 break; } //列表 if(str.length()>=2 && str.substr(0,2) == "* ") article.push_back({1,standard(str.substr(2))}); //段落 else article.push_back({2,standard(str)}); bool check=false; while(getline(cin,str)) { //是空行 if(isspace(str)) check=true; else { //上一行是空行,该行非空,直接插入 if(check) { check=false; //开启列表 if(str.length()>=2 && str.substr(0,2) == "* ") article.push_back({1,standard(str.substr(2))}); //开启段落 else article.push_back({2,standard(str)}); } //上一行非空,那就要考虑是否是同一段/同一列表了 else { Markdown &temp=article.back(); //列表情况 if(temp.type==1||temp.type==3) { //本列表项内容,直接连结 if(str.length()>=2 && str.substr(0,2) == " ") { temp.s+=" "; temp.s += standard(str.substr(2)); } //列表非首项 else if(str.length()>=2 && str.substr(0,2) == "* ") article.push_back({3,standard(str.substr(2))}); //新段落 else article.push_back({2, standard(str)}); } //段落情况 else { //开启新列表 if(str.length()>=2 && str.substr(0,2) == "* ") article.push_back({1,standard(str.substr(2))}); //本段内容,直接连接 else { temp.s+=" "; temp.s += standard(str); } } } } } long long ans=0; for(int i=0;i<article.size();i++) { string& str=article[i].s; //新的段落或列表,空一行 if(article[i].type!=3 && i>0) ans++; //列表的处理 if(article[i].type!=2) { //空项目(注意上面的处理方式,如果非空会连结上内容的) if(str.size()==0) ans++; //注意同一项目第一行 空格 * 空格 /非第一行要插入三个空格 else { for (int i = 0; i < str.length(); i += (n - 3)) { //换行时去掉前导空格 while(i<str.length()&&str[i]==' ') i++; ans++; } } } //段落的处理 else { for (int i = 0; i < str.length(); i += n) { //换行时去掉前导空格 while(i<str.length()&&str[i]==' ') i++; ans++; } } } cout<<ans<<endl; return 0; } /* 10 * CSP * CSP is * a real competition. * * ome! and join. *Tel: * 12345 * */
-
后记:
- 写大模拟题,思路一定不能乱,看题要仔细,最好拿个纸把关键信息提取出来。
- 虽然看题要花挺久的,但是也不能因为耽误时间长就着急动手,一定要先想好处理过程,边写边想会越写越乱,最后心态就不行了。
- 像这个题,如果过程太复杂,可以考虑把复杂的过程分成几部分处理,这样思路更清晰。做模拟题思路清晰就是王道
CSP 202006-3 Markdown渲染器
最新推荐文章于 2025-03-30 09:19:51 发布