让我们一起来备战蓝桥杯与CCF-CSP吧之大模拟之模板生成系统

由于之前蓝桥杯省三被打击发了个动态:没想到得到了很多小伙伴的鼓励,也很荣幸得到了很多小伙伴的关注。
在这里插入图片描述
但是由于忙着写作业,完成实验室项目任务,但是我也在很尽量的抽时间刷题,这不干的了两点,想着大家都在鼓励我,我也不能辜负大家,所以决定把我自己的备战思路和刷题中遇到的知识点以及经验分享给大家,也算是给自己的刷题之路来一个记录吧,希望可以和大家一起学习成长!。

先说我备战的想法:

  1. 来自自身
    由于我目前绩点在专业前2%,学校也有一定的保研名额,所以我很有可能会花较多的时间在必修课来稳住自己的排名,同时保研并不是绩点决定一切,还有加分(最大加5分),我们学校ccf-csp认证300分以上就可以加3分,所以我刷题肯定是优先针对ccf-csp。
  2. 来自比赛
    从第一点我们知道了自己要准备什么比赛,那就可以去了解这个比赛出题的风格,以ccf-csp为例,以我对这个比赛的理解:
    第一题:会语言就能满分。
    第二题:一般来说暴力能得70分,想要满分必须要会一些基础算法(前缀和,差分,二维前缀和等)和数据结构知识和思维
    第3题:大模拟
    第4,5题:dp等偏难知识。
    既然这样,我们目标300分,前1,2题肯定必须拿满,如果你算法能力并不强。练练爆搜(对蓝桥杯有非常有用,会爆搜一般来说想想省一问题不大,可惜以前自己掌握不牢,所以爆搜也要练)什么的看看能不能骗点4,5题的分,然后就是恶心自己,苦练大模拟。就我而言,我觉得学dp,线段树什么的会更恶心,因为你学了不一定会有什么收获,而大模拟就不一样了,首先它不用用到太多的算法,其次,我相信大家算法不强大概率都是走除算法以外的路了,例如开发,而大模拟其实你就可以把他当作用户给你的一个项目来写,非常可以锻炼自己的码力以及细节处理能力。这样我们东拼西凑说不定可以有300分。
  3. 一定要有支撑你学习的地方
    什么是支撑你学习的地方,就是你可以学到算法的地方,可以是书,可以是视频,我选择的ACwing,这里并不是打广告,只是觉得ACwing确实可以,课程便宜,有题库,y总讲的也不错,所以觉得可以推荐给大家,当然,大家选择自己喜欢的就好,但是建议一定要有,不然容易被直接劝退。

说到这里,我们就有了明确目标。有了目标,就有了动力,我们开始刷题,所以我准备先刷往年的ccf-csp的大模拟题,也就是第3题。

我今天刷的题是2015-9月:模板生成系统
大家可以点击链接前往:
由于题过于长以及图片较多,我就不再为大家赘述。

由于之前大一都习惯用数组,所以对STL容器也并不是特别了解,但是我觉得会用STL容器是非常有必要的,因为这次蓝桥杯考试我就因为数组开小的本来应该开10000,不知道为什么当时只开了100,导致肯定会丢分,所以我决定带大家一起来了解下这题会用到的STL容器以及他们最常见的用法

1.vector
vector是变长数组,支持随机访问,不支持在任意位置O(1)插入。为了保证效率,元素的增删一般应该在末尾进行。

声明
	#include <vector> 	头文件
	vector<int> a;		相当于一个长度动态变化的int数组
	vector<int> b[233];	相当于第一维长233,第二位长度动态变化的int数组
	struct rec{…};
	vector<rec> c;		自定义的结构体类型也可以保存在vector中

size与empty函数
size函数返回vector的实际长度(包含的元素个数),empty函数返回一个bool类型,表明vector是否为空。二者的时间复杂度都是O(1)。
所有的STL容器都支持这两个方法,含义也相同,之后我们就不再重复给出。
clear
clear函数把vector清空。
在这里插入图片描述上图是上述三个函数的用法
push_back() 和 pop_back()
a.push_back(x) 把元素x插入到vector a的尾部。
在这里插入图片描述

b.pop_back() 删除vector a的最后一个元素。

在这里插入图片描述
2.map(虽然我们题目中用的是unordered_map,但是区别不大的
map容器是一个键值对key-value的映射,其内部实现是一棵以key为关键码的红黑树。Map的key和value可以是任意类型,其中key必须定义小于号运算符。

声明
	map<key_type, value_type> name;
	例如:
	map<long, long, bool> vis;
	map<string, int> hash;
	map<pair<int, int>, vector<int>> test;

find
h.find(x) 在变量名为h的map中查找key为x的二元组。
[]操作符
h[key] 返回key映射的value的引用,时间复杂度为O(logn)。
[]操作符是map最吸引人的地方。我们可以很方便地通过h[key]来得到key对应的value,还可以对h[key]进行赋值操作,改变key对应的value。

本题还用到了getchar()方法,这个方法的作用是将从缓冲区读一个字符,返回值是该字符的ascii码。除了用在读一个字符的时候,还主要用来取走上一次输入的回车,保障接下来的字符输入.

讲完最简单的用法,就来讲讲我是如何来模拟这个题的,我们边看代码边说:

#include<iostream>
#include<unordered_map>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
int n,m;
unordered_map<string,string>vars;
vector<string>sm;
int main()
{
    cin>>n>>m;//读入n,m;
    getchar();//处理输入n,m的换行
    while(n--)
    {
        string s;
        getline(cin,s);//由于语句有空格,所以需要用getline读入,并且在头string.h里
        sm.push_back(s);
    }
   
    while(m--)
    {
        string key="",value="";
        char c;
        cin>>key;
        while(c=getchar() , c!='\"');//这里就是用于读入字符
        
        while(c=getchar() , c!='\"') value+=c;
        vars[key]=value;
    }
    for(auto& s:sm)
    {
        for(int i=0; i < s.size(); i++)
        {
            if(i+1<s.size() && s[i] == '{' && s[i+1]=='{')//大家要注意一定要把i+1的判断写在前面,不然直接在s[i+1]就越界了,后面判断了也没有用
            {
                string ans;
                int j=i+3;//i+3是因为3分别是字符{,{,空格
                while(s[j]!=' ')
                {
                    ans+=s[j++];
                }
                cout<<vars[ans];
                i=j+3;//和前面的3相反,空格,{,{
            }
            cout<<s[i];
        }
        cout<<endl;
    }
    return 0;
}

就在我以为完事之际代码在ACwing上一交,只过了一个点:
在这里插入图片描述
啊这,debug了会,又改成了下面的代码:

 #include<iostream>
#include<unordered_map>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
int n,m;
unordered_map<string,string>vars;
vector<string>sm;
int main()
{
    cin>>n>>m;//读入n,m;
    getchar();//处理输入n,m的换行
    while(n--)
    {
        string s;
        getline(cin,s);//由于语句有空格,所以需要用getline读入
        sm.push_back(s);
    }
   
    while(m--)
    {
        string key="",value="";
        char c;
        cin>>key;
        while(c=getchar() , c!='\"');
        
        while(c=getchar() , c!='\"') value+=c;
        vars[key]=value;
    }
    for(auto& s:sm)
    {
        for(int i=0; i < s.size(); i++)
        {
            if(i+1<s.size() && s[i] == '{' && s[i+1]=='{')
            {
                string ans;
                int j=i+3;
                while(s[j]!=' '|| s[j + 1] != '}' || s[j + 2] != '}')
                {
                    ans+=s[j++];
                }
                cout<<vars[ans];
                i=j+3;
            }
            if(i<s.size())//修改的地方
            cout<<s[i];
        }
        cout<<endl;
    }
    return 0;
}

再交,过了两个点…
在这里插入图片描述好家伙,我对比了下y总的代码,发现差别并不大,我决定去官网交,两个版本的代码都是80%,还得一说凌晨两点的评测姬速度就是快
在这里插入图片描述好家伙,这y总数据就是牛,我寻思既然ACwing和官网加起来100,我就勉强放过自己吧!hhh

5.7日更新内容:
在刷另一题的时候发现了这题的bug,bug在那里请大家看下面代码:

 #include<iostream>
#include<unordered_map>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
int n,m;
unordered_map<string,string>vars;
vector<string>sm;
int main()
{
    cin>>n>>m;//读入n,m;
    getchar();//处理输入n,m的换行
    while(n--)
    {
        string s;
        getline(cin,s);//由于语句有空格,所以需要用getline读入
        sm.push_back(s);
    }
   
    while(m--)
    {
        string key="",value="";
        char c;
        cin>>key;
        while(c=getchar() , c!='\"');
        
        while(c=getchar() , c!='\"') value+=c;
        vars[key]=value;
    }
    for(auto& s:sm)
    {
        for(int i=0; i < s.size();)
        {
            if(i+1<s.size() && s[i] == '{' && s[i+1]=='{')
            {
                string ans;
                int j=i+3;
                while(s[j]!=' ')
                {
                    ans+=s[j++];
                }
                cout<<vars[ans];
                i=j+3;
            }
            else//这里加else,因为不然会多输出东西!
            cout<<s[i++];
        }
        cout<<endl;
    }
    return 0;
}

改了之后,Acwing和官网都ac啦!!!

接下来放y总代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <vector>

using namespace std;

int n, m;
vector<string> strs;
unordered_map<string, string> vars;

int main()
{
    cin >> n >> m;
    getchar();  // 过滤掉第一行的回车
    while (n -- )
    {
        string str;
        getline(cin, str);
        strs.push_back(str);
    }
    while (m -- )
    {
        string key, value;
        cin >> key;
        char c;
        while (c = getchar(), c != '\"');
        while (c = getchar(), c != '\"') value += c;
        vars[key] = value;
    }

    for (auto& str: strs)
    {
        for (int i = 0; i < str.size();)
            if (i + 1 < str.size() && str[i] == '{' && str[i + 1] == '{')
            {
                int j = i + 3;
                string key;
                while (str[j] != ' ' || str[j + 1] != '}' || str[j + 2] != '}')
                    key += str[j ++ ];
                cout << vars[key];
                i = j + 3;
            }
            else cout << str[ i ++ ];
        cout << endl;
    }
    return 0;
}

作者:yxc
链接:https://www.acwing.com/activity/content/code/content/872378/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

嗯,今天就这样吧,写完这篇博客也3点了,希望能够对大家有帮助就好!

最重要的是,希望来个大佬指出下我代码bug在哪里呀,也欢迎大家评论区里互相讨论,我们一起学习!

  • 16
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

工藤学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值