栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

CSP CCF: 202006-3 MarkDown渲染器 (C++) 40分

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CSP CCF: 202006-3 MarkDown渲染器 (C++) 40分

目录
  • 题目来源
  • 知识点
  • 注意点
  • 10分
  • 20分
  • 40分
    • 思路
    • 代码
  • 80

题目来源

CSP MarkDown渲染器

知识点
  1. eof() 函数: 按题意需要 !cin.eof() 。 cin 是输入来源, cin.eof() == true 是 cin 中的数据到达了末尾。

  2. getline() 函数: 按题意需要 getline(cin, str)。 cin 是输入来源, str 是接受字符的变量名。

  3. 他俩都不需要头文件。

  4. substr的用法

     str1 = "I live in China."
     str2 =  str1.substr(2, 4)    //str1.substr(pos, len);  pos: 下标, len:长度
     cout< 
注意点
  1. 注释掉 isftream !!!
  2. 除了有字符的行外, 段落、项目列表间的空行也要算上。
10分

数据特征: 仅包含段落, 每个段落仅包含一行, 每行文本长度不超过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 = "<
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/870260.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号