不知不觉NOIP2018临近了,我的高中OI生涯也很可能快要结束了(if(score<500) break; else continue;),不管结果怎样,全力以赴就可以了,但是,我们不能让低级错误让我们丢分,所以我写下了这篇文章。(不定时更新)
注意:以下是在windows考试环境下的
注意事项:
PART 1:写完代码之前
1.保持好的心态(不多说)
2.审题:
这一点非常重要,一旦审题错误或者理解错误就可能造成你花很多时间写出来的程序WA,如果检查出来了,你浪费的是时间,如果没有发现,你丢掉的是分数和前途(说严重了?)
解决方法:写代码前先把题读懂,读透,然后想出算法后才开始写
3.考虑严谨:
这一点也相当重要,如果考虑不严谨就可能被特殊数据卡分[0,100],例如:
这道题很多人都会采用状态压缩,把间隔大于100的石头压缩为距离等于100,然后动态规划,写完了,再然后80分
这样就丢掉了20分,为什么呢?
当S==T时显然不能压缩,这就是丢分原因
解决方法:先要审题,然后要考虑特殊情况
4.代码正确:
也就是说,你写代码时要争取一次写对。如果你写的代码有bug,那就需要查错,而查错需要的时间在(0,+inf),考试的时候查错花大量时间是不划算的。
解决方法:写一行,看一行,每写完一行,就考虑一下是否可能写错(for循环边界,格式控制符,i,j混淆......)
PART 2:写完代码之后
5.freopen:
文件输入输出是非常重要的一部分,一旦写错一点,就会丢掉[0,100]的分数,且无法挽回
解决方法:(图片摘自:NOI2018笔试题库,可能和NOIP略有差异)
例:NOIP2017DAY2 T1 奶酪(cheese)
你的文件名:cheese.cpp
你的freopen:
freopen("cheese.in","r",stdin);
freopen("cheese.out","w",stdout);
注意千万不要写成chese等其他与要求不一致的单词
6.检查:
非常重要,但不多说,参考PART 1 中的2,3,4
还有注意检查你的程序是否在考试指定文件夹里面,而且不能存在指定文件夹的子文件夹里面
7.防爆(防止爆数组)
NOIP中爆数组是一件很糟糕的事,爆数组就0分
解决方法:数组定义要小于空间限制
用:printf("%.3f M\n",(double)sizeof(arr)/(1<<20)); 查看数组占用空间大小(单位:M)
PART 3 其他
8.头文件
解决方法:不知道CCF开放万能头文件的使用没有,所以建议头文件不要用#include<bits/stdc++.h>
因此头文件一定要写全,缺少必要头文件就是0分,同时不要用禁止使用的头文件(如:windows.h)
9.数据类型
一定要看题目数据范围,要考虑极端情况int是否足够,不够时要考虑(unsigned) long long甚至高精度
还要防止中间结果溢出!!!
未完待续... ...
考试技巧:
1.时间复杂度的选择
根据每道题数据范围选择适当时间复杂度的算法
如:n<=5000,000 就应该选择O(n)及以下的算法,O(nlogn)的算法可能会超时
如果n<=10^9(如NOIP2017DAY1T1) 那就需要O(logn)或O(1)的算法了(推结论)
2.利用Dev C++
如果你的考试环境使用Dev C++那么注意以下:
a.在工具->编译选项 中将代码警告选项调为显示最多警告信息,帮助你尽可能多的发现隐性错误
3.对拍(选学)
所谓对拍,就是写两份程序,一份是用于考试提交的,还有一份用于检查用于提交的代码是否正确
用于提交的那份代码当然要求尽可能多的得分,检查用代码要求答案尽可能完全正确(可以写暴力枚举程序),显然检查用程序很可能超时,因此,我们用它来进行检查,而不是提交。(再次重申:注意文件名和输入输出,还有不要交错了代码!)
对拍是DAOLAO考试时常会考虑的方法(当然要时间足够)
写对拍程序步骤:
a.写数据生成器
就是可以随机生成满足题目条件数据的程序,面对不好写的数据生成器,不建议采用对拍方法(如限制要求苛刻的图,树等)
数据生成器的核心当然是随机数的写法
详细教程链接:NULL(还没有写好,大家可以在网上搜索)
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++中的 //
c.写暴力程序
你需要熟悉各种暴力枚举方法:如:子集生成,排列生成,暴力搜索
然后暴力程序一定要写对
d.更多关于对拍器的介绍:https://blog.csdn.net/hi_ker/article/details/80671110
4.巧用cmd(选学)
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的目标文件夹里面
5.查错
之前讲了,写代码要尽量保证一次写对,但写错了有没有办法,需要查错
a.先检查算法是否正确,如果算法都不正确,不要慌,再想想,真的不正确那只有重写
b.如果不是算法问题,可以采取两种查错方式:静态查错,输出查错
所谓静态查错,就是讲代码用肉眼重新检查,观察可能错误的地方
所谓输出查错,就是一步一步输出中间结果(也可以用调试工具),按步骤排查错误
如果使用输出查错要注意提交之前将输出中间结果的语句删除或注释掉
6.“骗分”
当然不是靠作弊骗分,是靠“技巧”“骗分”
a.无解情况
这道题很对于初学者很恼火,搜索+模拟不太好写,如果你是一个只要求NOIP150+的人,直接写一个输入数据然后输出-1的程序就可以了,这样可以得20分(注意:这种方法对于NOI一般不管用,NOI现在几乎所有题目每个测试点都有多组数据)
b.打表
对于数据小又容易超时的题,可以采取打表法
详细讲解:https://blog.csdn.net/Hi_KER/article/details/81188352
c.多次贪心
贪心不能解决的问题,可以尝试多次贪心
例如求最小值,你多想几个贪心算法,在贪心得到的答案中选最小的,可能会取得较好的效果
例如一道叫切割网线的搜索+剪枝+贪心题,我靠多次贪心水到了76分
未完待续... ...