我的程序评测就是不通过怎么办?

· · 个人记录

我的程序评测就是不通过怎么办?

一 前言

马上退役的我总结了一些些经验,希望能给初来乍到的同学们一些提示和帮助。(也只能对初来乍到的同学有帮助了)

当然,我的水平也远称不上是优秀,还望各位多多指教,有补充可以评论或者私信,想喷也可以直接开喷。

这里用kkk的一段文字引入:

在程序设计竞赛中,选手按照要求编写完程序后需要自己进行测试、保证程序符合题目要求,然后统一提交并进行评测。本书的编程例题大多也是符合这样的格式。读者可以去各个在线题库(即 Online Judge,例如洛谷)找到更多的题目并提交自己的代码让评测系统进行编译运行和评分。

出题人会生成构造多组测试数据,向选手编写的程序编译后的可执行文件输入,得到的选手输出和标准输出进行比对;如果选手输出和标准输出一致(或者通过特殊判断认为选手输出是合法的)就能够获得这部分的分数。如果输出了错误的答案或者运行时间过久、运行时错误等问题则不能得分。

摘自 kkksc03 我的程序评测不通过怎么办?

二 练习时

(1) 萌新常见错误qwq

如果你一个是刚学OI的新同学,那么遇到的问题很可能是下面几种当中的一种:

a. 为什么不过编译?

请尝试逐条阅读编译器的输出信息:

很多情况下这是由于你定义的变量或者函数和库里已有的函数重名了。如 y2() 等。

请检查你是否定义了此变量或函数,或者你没有使用该函数对应的头文件。

请检查语句末是否有分号或者括号是否对应。

很多情况下是你使用 STL 时出现了语法问题。数组开太大时也会编译错误。

在本机编译正确但提交编译错误也请查看编译信息调试。

此外,编译器显示错误零和答案正确完全不是一回事。

b. 样例过了但0分怎么办啊

可以手动编写样例,当然也可以直接下载数据来看看,当然,前提是你应确保自己的算法正确。

也可以输出中间变量来进行调试。

需要注意的错误有如下:

等等。

c. 为什么我本机过提交错啊啊啊

一大部分情况下是初始化的问题,此外也可检查数组越界等可能导致RE的错误。

d. 这个玩意怎么用?

你可以尝试搜索一下,在cppreference.com这个网站你可以找到比较详细的文档,不想看英文也可以在oiwiki.org进行学习。

e. 那你能帮帮我吗

可以,你可以到讨论区发帖,需要注意的是你应在对应题目讨论版发帖,并写上自己的代码,分数,或者编译信息等等,如果需要图片应使用图片上传功能,直接把图片拖进去别人是看不到的。只要你的题目不是很难,在很多情况下大家会帮助你。

除非你急需得到答案,那么没有必要发出多个帖子进行求助,当然你可以稍后捞一下你的帖子。

(2) 普遍错误

在讨论区发帖,回贴的人数和代码长度一般成反比,比如一个线段树模板的代码很少有人帮你调,而一个红题不一会就会有人帮你调。

其实调试的最好方法是避免调试,尽量一次写对,多想想,而不是想过会再来调,养成认真仔细的习惯,能避免很多问题,think twice,code once 不是白说的。

a. 自造边界样例 / 输出中间变量

如题,是很普遍的方法。

对于线段树等数据结构,可以尝试构造边界数据来检查错误。

对于图论,同样可以尝试构造奇奇怪怪的数据。

对于 dp,可以输出 dp 数组。

……

对于模拟题,我喜欢把输出部分写成一个函数来调用,这样会让冗长的模拟代码看起来舒服一点。

建议注释掉调试命令而不是删除调试命令,因为说不定待会还会用到。

b. 尝试使用 gdb 调试

dev 的调试实在是不大好用……当然,使用 vscode 等编辑器会方便许多。

需要注意的是使用 mingw 的 gdb 时应注意路径是否包含中文。

熟悉使用 gdb 的话效率也会很高,但由于我不大熟悉,所以暂不赘述。

c. 对着题解调试

也是很常见的方法,可以和题解对拍,并输出中间变量来看看哪里出了差错。

写数据结构或者大分块也可以把逐步替换成 std 看看哪里挂了。

此外调对过后应该明白自己的写法哪里出了问题,尽量避免无脑抄写。

d. 写一部分调一部分

比如说写树剖的时候,可以先把线段树码好,输入几个数试一试,再把树剖的部分写上。

这样能节省很多的时间,也能避免一些错误。

在很多数据结构题也可以使用这个方法。

e. ctrl+A delete

在你对自己的算法非常自信,时间非常充足的时候可以使用这个方法。

重构代码要做到果断删除,否则心态容易出问题,必须要求是对自己的码力和方法足够自信,对算法的了解足够透彻,那么使用这个方法是极有效的。

f. 我……是不是忘了什么

你可以想想你是不是漏掉了什么东西,比如:

无论比赛时还是练习时,编译时都开启 -Wall 选项,很多问题它都会报 warning。

g. 救救孩子!调了114514年了

到讨论区发帖前,可以在题目讨论区翻一翻帖子,许多普遍的问题都可以得到解决。如果没有翻到,那么可以新发一贴,但如果代码比较长很有可能得不到回复。另外得到答案后不必删除帖子,说不定以后还有人要看。

如果已经到了饭点或者已是半夜三更,那么还是先吃饭/睡觉比较好,毕竟心态炸了是很难调好代码的。

当然,如果第二天不用早起,那么先洗个澡刷好牙,不想调了直接睡觉也是不错的。

我可以理解你半夜三更调不好代码孤独无助的心情,你可以去水水讨论区或者翻翻朋友圈,乃至看看B站笑一笑也可以,等心态好了再来调代码。

放点喜欢的音乐是很好的,总而言之就是心态不能炸。

h. 靠怎么一个点TLE——常见卡常方法

inline void redn(int& ret) {
  ret=0;int f=1;char ch=getchar();
  while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
  while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
  ret*=f;
}

三 比赛时

(1) 我的程序为什么过不了样例!

这很正常,所以不要慌张,慢慢调试。

如果真的过了很久,那么可以去下洗手间或者吃点东西,也可以选择过会再来做这道题,同样也是心态千万不能崩。

另外在写程序前可以想想有的细节怎么写,直接开始写到了某个地方卡住容易影响心态。

比赛时比的一大部分就是心态,心态好了那么得高分的概率就不会低,这也是很多同学平常模拟赛不错,一到正式考试就挂的原因。学OI有助培养抗压能力

比如考着考着旁边同学开始玩扫雷/开始吃饭,这个时候就要尽量不受干扰。

比赛前要带足吃的,可以带点薯片,对缓解压力很有帮助。

即使没过样例也要将代码交了,期望能够玄学一点分数。

(2) 我不放心我的程序欸

这是一个常见的对拍程序(linux 下是 diff):

#include<bits/stdc++.h>
using namespace std;
int main(){
    while(1){
        system("gen.exe");
        system("a.exe");
        system("force.exe");
        if(system("fc a.out a.ans")){
            cout<<"WA"<<endl;
            return 0;
        }
        else cout<<"AC"<<endl;
    }
    return 0;
}

数据生成和暴力需自己编写,所以建议有足够时间的同学写对拍验证自己的程序。

(3) 卧槽我忘了这个东西怎么写了

还是写程序前可以想想有的细节怎么写,直接开始写到了某个地方卡住容易影响心态。

如果真遇到这种情况,也同样不能慌张,看看有没有什么替代方案或者想想实现原理说不定就想起来了。

这里主要写了避免心态爆炸的事,考场上还有很多注意事项这里也不多赘述,可以翻翻以前的日报。

尽人事,听天命,自己全力取得的最好的成绩,相信你不会为此感到后悔。

四 杂谈

对于新同学/xxs,我觉得我们应持包容的态度,毕竟我们也曾是 xxs,没有必要冷嘲热讽,对于求助帖子也可多看几眼,指不定就是你曾经犯过的错/将来会犯的错呢?

我想大家应该都体会过那种调不出来题爆炸的感觉,这个时候去洛谷发个帖子还没人理实在是太惨了……所以各位闲着没事的时候倒是可以帮人调调代码,调代码的时候可以跟楼主说一句我在看,让楼主感受感受洛谷的温暖。

新建这篇文章的时候是七夕节,祝大家调代码愉快并早日调对自己没有 npy 的 bug。