201703 CSP认证

分蛋糕 15ms

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n, k;
    cin >> n >> k;
    
    int sum = 0, cnt = 0;
    while(n --){
        int x; cin >> x;
        sum += x;
        if(sum >= k){
            sum = 0;
            cnt ++;
        }
    }
    if(sum)  cnt ++;
    cout << cnt;
    return 0;
}

学生排队 15ms
也写了老半天了脑子不清楚…
这里就没记录占位了,最后直接丢到优先队列里面让它排序从小到大给我输出

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N = 1010;
int loc[N];  //学号为i的学生的序号是loc[i]
int main()
{
    int n, m;  cin >> n >> m;
    for(int i = 1;i <= n;i ++) loc[i] = i;

    while(m --){
        int x, y; cin >> x >> y;
        int init = loc[x];
        if(y > 0){
            //向后移动
            loc[x] += y;
            for(int i = 1;i <= n;i ++)
                if(loc[i] >= init && loc[i] <= init + y  && i != x)
                    loc[i] --;   //依次进行前移
        }else {
            //向前移动
            loc[x] += y;
            for(int i = 1;i <= n;i ++)
                if(loc[i] >= init + y && loc[i] <= init - 1 && i != x)
                    loc[i] ++;   //依次后移
        }

    }
    
    

    PII t;
    priority_queue<PII, vector<PII>, greater<PII> > q;
    for(int i = 1;i <= n;i ++){
        t.first = loc[i];    //根据站位进行排序
        t.second = i;
        q.push(t);
    }
    while(!q.empty()){
        t = q.top(); q.pop();
        cout << t.second << " ";   //站位从小到大排序后输出
    }
    return 0;
}

第三题 Markdown
待更新…
先写写,等缝缝补补搞定再把代码贴上来…

2023/11/7 更新
虽然没写很多第三题…但感觉很多大型模拟题是这种转换类,输入通常用string类来接收,然后进行切分判断,而且通常伴随着有嵌套操作。在判断是否为A的同时还要考虑之间嵌套B的可能性

这里列举一些些在代码敲写的过程中觉得自己初写的时候没有考虑到和分析到的东西

  • 关于审题:其实关于题干后面对样例测试点的解释就可以看出,本题的转换主要分为三个。最简单的是标题的转化。段落和无序列表的转化我认为有两个难点,一个是它们不像标题只为单行输入,涉及到对多行的处理,因此当我输入选用getline(cin, line)时如果只对单行做处理,则会输出错误,此时的解决方法就是引入一个type变量,记录前一行的输入类型,该变量当且仅当读入一个空行时进行转变;第二个难点就是行内中会出现p以及em,且出现还涉及到二者相互嵌套问题
  • 关于嵌套的行内处理:虽然写的题不多哈…但是大部分嵌套的处理就是提取功能函数;提取到对称的标识符后,比如本题的偶数出现的_[],()等,截取子串丢入对应的功能函数处理。在功能函数处理的同时也不要忘了提取,可能出现嵌套在内部的另外一个结构。提取出来后再度丢入对应的功能函数即可
  • 本题还有一个输出的处理,明确哪里有endl哪里没有
  • 对于空格的处理,哪里的空格需要处理,哪里的空格不需要处理(位于文本内部的空格不需要处理),因此需要辨别出从哪个字段开始是真正的行内文本
  • 对于字符串的计数i要很细心很细心,哪个不应该输出哪个应该输出、下标到底是从哪里到哪里要切分出来交给对应的功能函数,否则很可能由于样例不全找不出错误来

下面贴出来一段自己调整过的满分代码(通过平台),借鉴了 CSP认证:Markdown 的代码

#include<bits/stdc++.h>
using namespace std;
int pre = 0;  //这里用来记录上一行的类型(自写的时候也遇到了这个问题,按行读入的时候,若没有记录,无法在p和ul的末尾输出)

//这里因为是第一个函数,在c++中会向前找函数,所以这里要在函数内部就处理好<em>标签
void get_link(string str)
{
    string text = "", link = "";
    int i;

    for(i = 1;str[i] != ']';i ++){
        if(str[i] == '_') {
            text += "<em>";
            i ++;
            while(str[i] != '_') text += str[i ++];
            text += "</em>";
        }
        else text += str[i];
    }

    // find link
    for(i = i + 2; str[i] != ')';i ++){
        if(str[i] == '_') {
            link += "<em>";
            i ++;
            while(str[i] != '_') ;link += str[i ++];
            link += "</em>";
        }
        else link += str[i];
    }

    cout<< "<a href="<< '\"'<< link<< '\"'<< '>'<< text<< "</a>";
}

void get_em(string str)
{
    cout << "<em>";
    //处理嵌套
    for(int i = 1;i < str.size() - 1;i ++){
        if(str[i] == '['){
            int j = i + 1;
            while(str[j] != ')') j ++;
            get_link(str.substr(i, j - i + 1));
            i = j;
        }

        else cout << str[i];
    }
    cout << "</em>";
}

//用来处理行内;
//因为传入的仅仅只是一行,可能是p的起始行也有可能为中间行,使得对<p>的输出很麻烦,干脆函数内部不去处理
void paragraph(string line)
{
    for(int i = 0;i < line.size();i ++){
        // find str like "_text_"
        if(line[i] == '_') {
            int j = i + 1;
            while(line[j] != '_') j ++;
            get_em(line.substr(i, j - i + 1));
            i = j;
        }
        else if(line[i] == '[') {
            int j = i + 1;
            while(line[j] != ')')  j ++;
            get_link(line.substr(i, j - i + 1));
            i = j;
        }
        else cout << line[i];  //belong to normal paragraph, print directly
    }
}

void title(string line)
{
    int cnt = 0, i = 0;
    while(line[i] == '#' || line[i] == ' '){
        if(line[i] == '#') cnt ++;
        i ++;
    }
    string str = line.substr(i);
    cout<< "<h"<< cnt<< ">";
    paragraph(str);
    cout<< "</h"<< cnt<< ">"<< endl;
}

void ulist(string line)
{
    if(pre == 0)  cout << "<ul>" << endl;

    int i = 0;
    while(line[i] == '*' || line[i] == ' ') i ++;
    cout << "<li>";
    paragraph(line.substr(i));
    cout << "</li>" << endl;
    pre = 2;
}

int main()
{
    string line; pre = 0;

    while(getline(cin, line)){
        if(!line.size()) {
            if(pre == 2)  cout << "</ul>" << endl;
            else if(pre == 3)  cout << "</p>" << endl;
            pre = 0;  continue;
        }

        if(line[0] == '#')  title(line), pre = 1;
        else if(line[0] == '*')  ulist(line), pre = 2;
        else {
            if(pre == 0) cout << "<p>";
            else if(pre == 3) cout << endl;
            paragraph(line);
            pre = 3;
        }
    }

    if(pre == 2) cout << "</ul>" << endl;
    else if(pre == 3) cout << "</p>" << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值