10月份,CSP-J/S第二轮认证考试即将来临,不同于第一轮的单选/判断的考题形式,第二轮,代码要敲起来,与初赛相比,复赛有哪些特点?

在CSP初赛比赛中,主要考察的是参赛选手的编程、信息学方面的理论知识,而复赛才是真正考察参赛选手代码能力,也就是程序设计及上机编程能力。

相比于初赛,复赛对考生的基础要求是熟练掌握基础语法和算法,能够独立编写正确的代码,能够利用常见算法解题,能够根据题目优化代码,能够对代码进行查错和调试,甚至可以构造数据进行对拍。

每年在CSP-JS第二轮认证考试中,都有很多学生“挥斥方遒忙活半天,一查分数意外爆零”,因为一些低级失误导致“爆零”,即得0分。

根据历年考生们的反馈,80%考生爆零的原因是:

一、文件输入输出错误

在复赛考试中,需要使用freopen函数来进行输入输出重定向,而这个函数需要使用万能头文件

#include<bits/stdc++.h>。

image.png 文件输入输出有多种方式,最简单的是freopen。假如题目的标题是abc,则只需要加入这两行:

freopen(“abc.in”, “r”, stdin);
freopen(“abc.out”, “w”, stdout);

注意,这里的函数名称和参数不能写错,任意一个地方出错都会导致程序爆0。比如,abc.in不能写成abc.txt,也不能写成abc.in.txt。

“r”不能写成“read”,也不能写成’r’(这种情况编译器会报错)。注意一定是双引号的“r”和“w”!

两行freopen中的三个参数,是分别相反的,in文件对应着out文件,读取对应着写入,标准输入对应着标准输出。

另外建议不要在程序的末尾写fclose函数。因为程序结束后,所占的内存就都释放了,fclose函数写不写是一样的。新手写的越多,意味着犯错的可能性越大。

考试的时候直接用以上程序框架就行,然后在freopen()下面开始写程序。学生做题时为了方便测试,可以暂时先把两个freopen()注释掉,但是最终提交的程序里面一定要有freopen()做文件输入输出重定向。

二、文件输入输出错误

每个题目的输入输出文件的名字都是试卷上给出的固定名字,千万不要写错,注意大小写敏感。有些Windows系统的电脑的扩展名是隐藏的,一定要让扩展名显示出来。否则轻则影响测试,重则爆0。比如有些机器隐藏了扩展名,选手将程序命名为abc.cpp,实际上是abc.cpp.cpp;选手将输入文件命名为abc.in,实际上是abc.in.txt。

image.png

image.png

三、调试代码未注释或删除

有些同学为了调试代码,写了一些用于辅助输出语句,记住调试完成后一定要将这些语句删除或者注释掉,否则“爆零”!

四、数组开的太大

C++里数组有时候可能会出现莫名其妙的问题,所以一定要记得把数组开大点,并且赋初值。但,数组如果开的太大,会导致内存超限错误或者运行错误,我们数组的大小顶多开到10^7左右,如果确实需要更大的数组,首先尝试优化算法的空间使用,实在找不到优化算法,可以用vector动态数据,map模拟一维数组,map>模拟二维数组等方法解决。 数组建议用全局数组,全局数组可用的内存空间比局部数组可用的内存空间大很多很多,二维数组很容易就爆了。

五、变量初始化

变量的初始化常见有两种方式:输入和赋值。在使用变量之前记得要初始化。如果定义成全局变量,则系统会自动初始化。

六、输出格式

如果题目要求数据之间加空格,那就不能换行输出。比如要求输出

1 2 3

如果选手输出

1

2

3

则不能得分。

大小写也要注意,需要仔细看清题目是要求全大写、全小写还是首字母大写。比如要求输出Yes,则输出YES、yes、yES等均不能得分。

八、变量名冲突

用了using namespace std;之后容易产生的问题是,有些自己的变量名比如time、next和std命名空间中的变量名冲突,而且在Windows下编译器不报错,但是在Linux下报错。所以如果需要这几个单词,可以使用首字母大写Time、Next;或者做一下变形,比如tim、nxt;或者定义成局部变量。另外time、next等作为结构体的成员名是没问题的。

全局变量不要使用y0、y1、yn、j0、j1、jn。因为这些变量名称在C++11标准库里被定义了,不能再用作全局变量,否则编译会有警告或出错。但是这些变量可以用作局部变量。

九.时间和空间限制

1秒内最大循环次数不要超过1亿次。1亿次有可能超时也有可能不超时。但是一两千万次通常不会超时。

通常题目会限制内存不能超过256兆或512兆。所以要学会估计内存。比如全局数组int a[1000000]占内存100 0000 * 4 / (1024 * 1024) 兆 ≈ 4兆。

比赛时的一些建议

输入输出数据量比较大的情况一定要使用scanf printf,使用cin cout会出现超时错误。 对字符串的处理不要用gets,可以使用:fgets、getchar、scanf、getline。 数组定义全局变量优先,根据题意开数组大小,可以比题目要求稍微大一点,但是若题目要求的数组数量太大时可以使用vector动态数据控制内存的使用或者用map模拟数组使用。 小心爆int,爆long long。(注意long long格式控制符是%lld) 对于浮点数全都统一用double,不要用float。(注意double格式控制符是%lf)