(按照考试解题流程介绍)
考试前
考试前不要过于紧张,可以回忆一下以前考试常用的技巧,易错点和“骗分方法等”
考试中
这一点非常重要,一旦审题错误或者理解错误就可能造成你花很多时间写出来的程序WA,如果检查出来了,你浪费的是时间,如果没有发现,你丢掉的是分数和前途
解决方法:写代码前先把题读懂,读透,然后想出算法后才开始写代码
这一点也相当重要,如果考虑不严谨就可能被特殊数据卡分[0,100]
而特殊数据往往分为极端数据和特殊数据。
极端数据会按数据最大范围来,所以要注意空间是否足够,int是否会溢出;
特殊数据往往是具有特殊情况或性质的数据往往需要特判。
解决方法:先要审题,然后要考虑特殊情况和极端情况
也就是说,你写代码时要争取一次写对。如果你写的代码有bug,那就需要查错,而查错需要的时间在(0,3.5h),考试的时候查错花大量时间是不划算的。
解决方法:在想出具体算法后才开始写代码。写代码的时候要写一行,看一行,每写完一行,就考虑一下是否可能写错(for循环边界,格式控制符,i,j混淆......),还要加强静态查错
文件输入输出是非常重要的一部分,一旦写错一点,就会丢掉该题的全部分数
解决方法:(图片摘自NOI2018笔试题库)
例:NOIP2017DAY2 T1 奶酪(cheese)
你的文件名:cheese.cpp
你的freopen:
freopen("cheese.in","r",stdin);
freopen("cheese.out","w",stdout);
注意千万不要写成chese等其他与要求不一致的单词,所以建议复制粘贴题目中的英文名
考试中的检查
非常重要,需要综合注意事项中的2,3,4,5,7,以及考试技巧中的的对拍
还有注意检查你的程序是否在考试指定文件夹里面,名称是否正确
1.NOIP中爆数组是一件很糟糕的事,爆数组就0分
解决方法:数组定义要小于空间限制
用:
printf("%.3f M\n",(double)sizeof(arr)/(1<<20));
查看数组占用空间大小(单位:M),其中arr表示需要查看的数组
2.还要防止数组开小“防爆”(RE)
注意看清题目数据范围,数组范围开小了会导致数组越界从而RE
就在刚才我因为看错数据范围,数组开小导致100分变20分
解决方法:不知道CCF开放万能头文件的使用没有(部分省份以经开放),建议不要冒险,建议头文件不要用#include
如果不用万能头文件,那头文件一定要写全,缺少必要头文件就是0分,同时不要用禁止使用的头文件(如:windows.h)
一定要看题目数据范围,要考虑极端情况int是否足够。有句话说得好:十年竞赛一场空,没写long long见祖宗!不够时要考虑(unsigned) long long甚至高精度
还要防止中间结果溢出!!!
鲁棒性是什么呢?(鲁棒是Robust的音译,也就是健壮和强壮的意思)你可以把它理解为程序面对某些极端情况甚至数据不符
合数据范围下仍然可以不RE,得出正确答案
解决方法:在你时间做完题后时间充裕的情况下可以考虑增加程序鲁棒性
一定要注意以下错误:
a.缺少某些重要头文件
b.下标越界
c.中间结果溢出
d.该用long long却用了int
下面说明:
a.比如没有写#include
b.这个错误非常恼火,因为在自己电脑上运行,不严重的下标越界不会引起程序RE,而在很多OJ上,下标越界就RE,这样的错误确实难以发现
c.如果会发生这样的情况请计算时使用强制类型转换
d.比如:选择客栈,如果不分析用了int就会丢分
注意:以下讨论主要是基于windows考试环境
根据每道题数据范围选择适当时间复杂度的算法
如:n<=5000,000 就应该选择O(n)及以下的算法,O(nlogn)的算法可能会超时
如果n<=10^9(如NOIP2017DAY1T1) 那就需要O(logn)或O(1)的算法了(推结论)
如果你的考试环境使用Dev C++那么注意以下:
a.在工具->编译选项 中将代码警告选项调为显示最多警告信息,帮助你尽可能多的发现隐性错误
其他见:信息竞赛:DEV C++常用技巧
a.启动目标在当前文件夹的cmd
先写一个bat程序: start cmd
没错,就一行,两个单词
但是这个bat文件千万不要保存名称为cmd.bat,否则它会不停启动自己,然后你考试就会受到影响(非常重要)
看,划线的地方就是目标地址
b.使用cmd对比数据
标准数据太长的时候,肉眼观察肯定是一件恼火的事情,这里我们用fc(file compare?)
格式: fc ans1.txt ans2.txt
ans1.txt ans2.txt 代表两个不同的需要对比的文件,但是注意fc比较时不会忽略行末空格
注意ans1.txt ans2.txt必须在cmd的目标文件夹里面
c.启动你的程序
格式: code.exe < in.txt > out.txt
表示启动名叫code的exe程序并输入in.txt的内容,再将输出的内容保存到out.txt 中,这样你不需要用freopen
注意code.exe必须在cmd的目标文件夹里面
如果想学习这个,请先理解上一块:3.巧用cmd(选学)
所谓对拍,就是写两份程序,一份是用于考试提交的,还有一份用于检查用于提交的代码是否正确
用于提交的那份代码当然要求尽可能多的得分,检查用代码要求答案尽可能完全正确(可以写暴力枚举程序),显然检查用程序很可能超时,因此,我们用它来进行检查,而不是提交。(再次重申:注意文件名和输入输出,还有不要交错了代码!)
对拍是DAOLAO考试时常会考虑的方法(当然要时间足够)
写对拍程序步骤:
a.写数据生成器(信息竞赛数据生成器制作)
就是可以随机生成满足题目条件数据的程序,面对不好写的数据生成器,不建议采用对拍方法(如限制要求苛刻的图)
数据生成器的核心当然是随机数的写法
b.写对拍器
我们常用的写法是写一个bat(批处理)程序,请熟记下面的代码:(当然不用记注释)
@echo off
for /l %%i in (1,1,10) do ( ::for循环,相当于for(int i=1;i<=10;i+=1)
randdata.exe > in.txt ::启动数据生成器
std.exe < in.txt > out1.txt ::启动暴力程序,并输入数据,输出数据
cd.exe < in.txt > out2.txt ::启动要提交的程序
fc out1.txt out2.txt > result.txt
::对比结果
if not errorlevel 1 echo %%i:Accepted!
::显示提示
if errorlevel 1 (
echo %%i:UnAccepted!
pause
)
)
pause ::暂停
其中的::是注释用的,相当于C++中的 //
将代码写入记事本然后保存为后缀名为.bat的文件即可
c.写暴力程序
你需要熟悉各种暴力枚举方法:如:子集生成,排列生成,暴力搜索
然后暴力程序一定要写对
特别注意:
在某些电脑上使用批处理命令可能会出现:
'xxxx' 不是内部或外部命令,也不是可运行的程序或批处理文件。
的情况,这时你会发现对拍器无法正常使用,如果出现我们可以尝试修改环境变量的方法来解决:
找到:计算机->属性->高级系统设置->环境变量->找到Path->编辑->修改为: %SystemRoot%\system32
之前讲了,写代码要尽量保证一次写对,但写错了有没有办法,需要查错
a.先检查算法是否正确,如果算法都不正确,不要慌,再想想,真的不正确那只有重写
b.如果不是算法问题,可以采取两种查错方式:静态查错,输出查错
所谓静态查错,就是讲代码用肉眼重新检查,观察可能错误的地方
所谓输出查错,就是一步一步输出中间结果(也可以用调试工具),按步骤排查错误
如果使用输出查错要注意提交之前将输出中间结果的语句删除或注释掉
当然不是靠作弊骗分,是靠“技巧”“骗分”
a.无解情况
例:NOIP2011DAY1T3
这道题很对于初学者很恼火,搜索+模拟不太好写,如果你是一个只要求NOIP150+的人,直接写一个输入数据然后输出-1的程序就可以了,这样可以得20分(注意:这种方法对于NOI一般不管用,NOI现在几乎所有题目每个测试点都有多组数据)
b.打表
对于数据小但是容易超时的题,可以采取打表法
详细讲解:https://blog.csdn.net/Hi_KER/article/details/81188352
c.多次贪心
贪心不能解决的问题,可以尝试多次贪心,比较好的骗分方法是随机化多重贪心(例如:NOIP2017宝藏)运气好可以的高分甚至满分
例如求最小值,你多想几个贪心算法,在所有贪心得到的答案中选最小的,可能会取得较好的效果
例如一道叫切割网线的搜索+剪枝+贪心题,我靠多次贪心水到了76分
d.推荐阅读:《骗分导论》,有数学竞赛版,信息竞赛版的,去网上搜索可以查到,有多个版本。虽然写作时间久远(2009及以前),但内容和骗分思想还是值得一看
NOIPDAY1模拟题:NOIP2018原创模拟赛DAY1
题解:【洛谷】NOIP2018原创模拟赛DAY1题解
NOIPDAY2模拟题:NOIP2018原创模拟赛DAY2
题解:【洛谷】NOIP2018原创模拟赛DAY2题解