GPLT团体天梯赛 — 比赛技巧及知识点
编程环境:
比赛时使用的编译器是Dev-C++,并没有Visual Studio这样的外挂,所以最好在比赛前使用一下Dev
Dev的默认编译环境与vs不同,需要手动设置Dev的C++标准,否则无法使用一些C++11的新特性,比如auto关键字【设置教程】
Dev的标准库有一定残缺,部分函数例如to_string()是没有的,需要使用一些C++14/17的特性的时候,不要指望用Dev能运行成功
Dev的调试功能比较难用,比较简单的办法是输出变量值来调试
题型分析:
L1:
L1有几道送分的题目,其他大多是来考察参赛者的逻辑思考能力以及对程序逻辑的掌控能力,L1的题目比较简单,出错往往是因为读题不仔细,尽量认真读题,轻敌出错的话,就有点得不偿失,争取以最快的时间完成L1的题目。
L2:
涉及到一些数据结构算法,结构主要是栈,树(搜索树),队列,并差集等,而算法主要是考察一些搜索算法(深度优先搜索算法,广度优先搜索算法),最短路径算法(Dijkstra算法,Floyd算法),去年(2019)考了的队列以及并差集算法。
L3:
L3的题型与L2类似,但难度稍大,另外会有一些跟实际开发相关的题目以及一些几何题目,近年的比赛还出现了一种比较特殊的题型,即答案不唯一,使用特殊裁判程序进行判定的题目(L3-012水果忍者,L3-024 Oriol和David),这类题目难度较大,需要理解题意,并且分析出题目的判定机制,才有解题思路。
时间优化:(写好的代码有测试点运行超时,可以暂时放下,不要继续浪费时间)
1、如果出现运行超时第一时间思考是否是因为非法输入导致死循环。
2、尽量使用scanf,printf,而不使用cin,cout(C++的IO存在缓存(可取消));
3、不要重复创建临时变量(创建一次,后面赋值);
for (int i = 0; i < 100; i++) { //错误用法
int t;
cin >> t;
}
int t;
for (int i = 0; i < 100; i++) { //正确
cin >> t;
}
4、使用引用访问容器中的元素(遍历,排序);
vector<int> vc{ 0,1,2,3 };
for (int i : vc) //错误
cout << i;
for (int& i : vc) //正确
cout << i;
5、使用unordered_map,unordered_set替换map,set可以提升效率,注意修改时同时修改头文件;
6、一般图论问题都可以用深搜,但效率较低,容易超时,单源最短路径——Dijkstra,连通度、集合图——并查集;
7、图论问题,当数据量十分庞大(一般超过10^3个结点),使用map做邻接表效率很低,所以邻接表能用数组尽量用数组;
8、为了实现排序功能,尽量使用sort对数组排序,而不要依赖与map和set的自动排序(map,set结构庞大);
9、一般递归算法都比较慢,深搜可以通过剪枝优化,并查集可以进行路径压缩提升效率。
10、当数组是有序的,可以考虑使用折半查找,<algorithm>库中提供了binary_search()函数
比赛技巧:
1、由于PAT的题目测试数据较少,所以有些题目可以适当投机取巧。
2、尽量一次写对,不要回头找bug。
3、为了方便函数调用,可以都用全局变量,但你得记住,这是个(坏习惯)
4、不确定数据多少的情况,不一定非要用动态数组,可以直接根据题目给的数据范围定义一个较大的数组(大小应大于题目所给的范围),一般情况下不会出现内存超限(数组大小别超过10^8,二维数组不能超过array[10000][10000])(坏习惯)
5、一般情况下答案错误很可能是漏了题目的关键信息。
6、格式错误是因为排版跟题目要求不同,可能会多空格或空行
7、段错误是由于非法访问才会导致的,所以一般情况下,出现段错误,是因为数组访问越界。
8、题目给的测试样例,一般是跟前面的测试点相对应的,最少得到这些测试点的分,其他的,适当取舍。
9、涉及到除法,需要考虑除数不能为0,一般会有一个测试点。
10、图论问题用深搜可以得到大部分的分。
11、选取适当的结构(容器)可以让思路更清晰。
12、熟悉编译器的调试功能可以更快的找出bug。
必备知识:
数据结构与算法:(结构、算法来源于生活,理解、不要记模板)
1、树:二叉树的遍历方式,平衡二叉树的建树过程,根据两种遍历来建树
2、图:深搜,广(层)搜,并查集(推荐博客)。
3、堆:堆结构,建堆过程(堆排序)。
4、链表:根据结点连接链表(一般通过结构体进行模拟)。
5、排序:熟悉快排和归并排序的排序过程
常用库、函数(黑科技):
容器:
字符串处理:
知识点 | 说明 | 推荐博客 |
string容器 | 封装了一些对字符串的常用操作 | 链接 |
regex正则表达式 | 使用正则表达式来替换、查找字符串 | 链接 |
stirngstream字符串IO类 | 使用字符串来进行IO操作 | 链接 |
常用字符处理函数 | isdigit(char ch) |
lambda表达式:
自定义排序:
类型转换:
数值边界:
数学函数:
auto关键字:根据赋值自动推导数据类型
堆:
常用功能函数:
查找
计数
倒序
2、sort函数排序,自定义结构体比较方式(可重载<,或重载())。
3、STL标准库 list , vector,queue,stack,map,set 的各种操作。
4、类型转换:(可以通过sscanf,sprintf转换)
char->int: -'0' int->char: +'0';
string->int:int stoi(string str) int->string: string to_string(int i) 同理有stof,atoi(char*->int)
5、类型判断:(都可以自己写)
比如 isdigit()判断为数字,反正你只要输入is,编译器后面会提示你有些什么函数,你翻译一下就知道功能了。
6、数组(容器)倒叙:
(1)倒叙函数:void reverse(typename begin,typename end);
(2)利用反向迭代器倒叙(构造 new string),以字符串str为例:
string s=string(str.rbegin(),str.rend()) or s.assign(str.rbegin(),str.rend());
7、auto关键字——(是不是突然知道了python不需用数据类型的秘密?=.=)
8、find函数:
string str; // string类成员函数:未找到返回string::npos
if (str.find("substr") != string::npos);
//do something
set<int> st;
if (st.find(0) != st.end()); //set、map成员函数:未找到返回尾迭代器
//do something
vector<int> vc;
if(find(vc.begin(), vc.end(), 0)!=vc.end()); //序列式容器可以通过algorithm库中find函数查找,未找到返回尾迭代器
//do something
9、find_if、count、count_if,transform....(不常用、可以自己实现)
更多推荐
所有评论(0)