信息学之于其他竞赛学科的不同,就在于需要通过写程序来表达自己的思维和想法。如何尽可能又快又好地调试程序,成了我们必须要思考的问题。相信很多同学都有过这样的经历:思考一个算法只花了半个小时,但是把这个算法写对却花了一天。思考与实现的时间往往不成正比。
下面是结合经验给出的一些小建议,仅供大家参考,也欢迎指正~
关于调试有一个大前提,就是思考的方向一定得严谨正确,因为思考决定实现,如果思考的时候有漏洞,那么实现的程序肯定也不强健。在想出算法之后不要急着实现,一定要认真反复地论证:我的算法每一步的定义是否严谨,是不是哪里还有漏洞,我的算法所得到的东西是否就是题目需要求解的。确认了自己的想法后再开始实现。
假设我们现在写完了一个程序:
第一步:静态查错(俗称裸眼观察^_^),即不测试数据,而是通过反复地看代码来检查。静态查错首先要检查是否有变量名打错,语法是否正确,你打的代码和你的想法是否相符。然后要分析代码的逻辑性是否严谨正确,是否能在所有情况下都能正确运行。最后还要验证是否在所有边界情况都能得到正确的解,包括数组是否开够,会不会有n=0的情况等等。静态查错是最有效的查错方法,为什么有的大牛能够一遍写对很复杂的代码,因为他们静态查错的能力非常之强,并且在敲程序的过程中就已经在静态查错了。在实践中,我建议大家尽量让自己的程序模块化(即一个函数做一件事情),然后检查的时候边看边打上注释,这样能让自己更清醒地判断,也方便以后能轻松阅读自己的程序。
第二步:动态查错,用数据来验证代码的正确性。人眼往往不可靠,我们需要用更安全的数据来判定。一般而言在普通的OI竞赛中,时间是比较充裕的,我们有时间来对拍。对拍需要三个程序,一个是你需要提交的标准程序(std),一个是能够通过部分数据的*力暴**程序(plain),一个是用来生成数据的程序(mk_data)。
关于plain程序,一般会比较好写,所以一定要认真检查,不要写错!
关于mk_data,一般需要得到一个随机的整数,c++语言写法如下:
我们可以运行一次mk_data,得到一组数据,然后分别用std和plain跑一遍,看结果是否一样。当然这样手动是比较麻烦的,我们可以用脚本来自动对拍,下面是windows下用bat脚本对拍的普通写法:
(约定plain的输出文件是1.out,std的输出文件是2.out)
将这一段话写在一个文本文件中,将其重命名为ck.bat,然后和上述三个程序放在同一文件夹下,双击ck.bat,就能够实现对拍了。对拍的优势在于能够近似模拟出出题人的数据来检验你的程序,一般在考场上通过了对拍的程序很难写挂。当然有的时候随机数据不一定能够满足我们的需求,这时候需要我们从出题人的角度出发,去构造一些最坏情况下的数据,来检验我们程序的强健性。
第三步:提交之前,检查文件名,再次编译程序,运行一遍样例,以防手抽。
静态差错大大降低了程序出错的概率,减少了动态调试的时间,动态查错给程序上了双保险,最后的检查防止了意外情况的出现。这样的程序的正确性能够大大提高。
在调试中,最关键的一点,是站在逻辑的高度去思考程序,而不是从某个数据的角度去查看变量,这样才能避免陷于调试的泥潭不能自拔。
对
拍
怎么写
在信息学竞赛中,尤其是考试的时候,经常会出现把水题写水的情况,而题目那一两个单薄的测试数据常常不足以让我们发现自己程序中的BUG。在竞赛时,水题悲剧了的话下场一定会很惨。在这种情况下,我们可以采用写一个对拍程序的方法来大大降低出错的可能。
基本思路 是对于一道题目来讲,写出高效算法后,时间充裕的情况下再写一个纯*力暴**的算法,写一个数据生成器,对你的程序和*力暴**程序的结果进行比对,出现错误后就人工 检查。一般来讲数据范围一开始可以小一点,小数据过了以后再慢慢扩大,为保证正确性你在写下一题的时候可以让对拍程序一直跑着。
这里的关键是要写一个批处理让Windows不停地反复执行这一操作,代码如下:

在文本文档中写好以后,扩展名保存为bat即可直接运行。
简单解释:
datamaker #数据生成器,生产随机数据到myprogram.in
std #纯*力暴**标准程序,从myprogram.in读入数据,运行后输出标准答案到std.out
myprogram #高效程序,即你最终要提交的程序,从myprogram.in读入数据,运行后输出标准答案到myprogram.out
对拍指的是用一个简单的程序去检测一个复杂的程序。 具体的方法就是: 1、随机生成n组数据。 2、用复杂的程序把数据跑一遍。(因为你要检查的就是这个程序,可能会有小漏洞,用这个可以检查出来)。 3、用简单的程序把数据跑一遍。(简单的程序不要错就行了) 4、对比两次的答案,如果不一样,你就要检查自己的程序了。 ACM的程序怎么设置对拍程序? 基本思路是对于一道题目来讲,写出高效算法后,时间充裕的情况下再写一个纯*力暴**的算法,写一个数据生成器,对你的程序和*力暴**程序的结果进行比对,出现错误后就人工检查。一般来讲数据范围一开始可以小一点,小数据过了以后再慢慢扩大,为保证正确性你在写下一题的时候可以让对拍程序一直跑着。 ---------------------对拍程序介绍,来自百度---------------------------- 在信息学竞赛中,尤其是考试的时候,经常会出现把水题写水的情况,而题目那一两个单薄的测试数据常常不足以让我们发现自己程序中的BUG。在竞赛时,水题悲剧了的话下场一定会很惨。在这种情况下,我们可以采用写一个对拍程序的方法来大大降低出错的可能。 基本思路是对于一道题目来讲,写出高效算法后,时间充裕的情况下再写一个纯*力暴**的算法,写一个数据生成器,对你的程序和*力暴**程序的结果进行比对,出现错误后就人工检查。一般来讲数据范围一开始可以小一点,小数据过了以后再慢慢扩大,为保证正确性你在写下一题的时候可以让对拍程序一直跑着。 这里的关键是要写一个批处理让Windows不停地反复执行这一操作,代码如下。 对拍程序的写法 如下

这里数据生成器: 就是你自己编写一个应用程序 rand*ex.e**,这个应用程序就是随机的生成一组符合题意的输入数据并存放到上边提到的 输入数据文件中data.in
高效程序:就是上边提到的 高效算法 写的程序,即 my*ex.e**
*力暴**程序 :就是指能够保证所有输入数据都能输出正确结果的 程序,即这里的std*ex.e**
上边的.bat文件 的功能就是循环 判断高效程序和 *力暴**程序 在同样的输入数据情况下,输出数据是否相同,从而实现了对拍程序的功能
比如举一个简单的例子: 求 1+2+3+……+n = ?
数据生成器:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
int n;
srand((int)time(0)); //调用srand()函数,以系统时间为随机种子
n = 1 + rand()%10000; //随机生成一个1到10000的自然数
printf("%d\n",n); // 输出随机生成的自然数
return 0;
}
//编译运行后,生成rand*ex.e**可执行文件 然后在批处理文件中 直接调用 rand*ex.e**>data.in即将上边的输出结果重定向到data.in文件中
*力暴**程序:算法 是直接从1加到n,执行n次循环 时间复杂度为 O(n)
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i,n;
long int sum = 0;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
sum += i;
}
printf("%d\n",sum);
return 0;
}
//编译运行后,生成std*ex.e**可执行文件 然后在批处理文件中 直接调用 std*ex.e**<data.in>std.out即将从data.in中获取输入,然后将输出结果重定向到std.out文件中
高效算法: 算法为 1+2+……+n = n*(n+1)/2, 时间复杂度为O(1)
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n;
long int sum = 0;
scanf("%d",&n);
sum = n*(n+1)/2;
printf("%d\n",sum);
return 0;
}
//编译运行后,生成my*ex.e**可执行文件 然后在批处理文件中 直接调用 my*ex.e**<data.in>std.out即将从data.in中获取输入,然后将输出结果重定向到my.out文件中
批处理文件 test.bat 内容如下
@echo off
:loop
rand*ex.e**>data.in
std*ex.e**<data.in>std.out
my*ex.e**<data.in>my.out
fc my.out std.out
if not errorlevel 1 goto loop
pause
goto loop
最后将这三个*ex.e**文件和批处理文件放到同一个目录下 运行批处理文件即可
所谓“对拍”,就是验算!写一个*力暴**(爆空间或者时间)的程序,去验算自己以为的正解。
1、正解·假:当时能想到的正解,不一定对,所以需要验算。
2、*力暴**程序:在特定数据范围内是对的,大数据会爆。但是能跑出正确的输出。
造数据程序(data*ex.e**),保证正确性的*力暴**程序(test*ex.e**)与测试程序(以moo*ex.e**为例)。
下面是对拍的代码思路,看不懂上面的同学可以看一下:
首先,新建一个文件夹,
然后,在里面放入biaoda*ex.e**,和test*ex.e**,还有data*ex.e**
biaoda*ex.e**是你*力暴**写的一个做法或者你从网上找的一份AC代码生成的程序,反正结果肯定是对的。
test*ex.e**就是你的代码生成的程序,你不知道他对不对或者你知道他是WA的但是你不知道哪里WA了,
data*ex.e**就是你的数据生成器,你可以用它去生成你认为的合法数据
比如
biaoda.cpp:
#include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout << a+b << endl;
return 0;
}
test.cpp:
#include <stdio.h>
int main()
{
int a, b;
scanf("%d %d",&a, &b);
printf("%d\n", a+b);
return 0;
}
然后就是data.cpp啦:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <algorithm>
#include <windows.h>
using namespace std;
//ofstream cout("data.in");
int main()
{
srand(time(0));
// srand( (unsigned)time( NULL ) );
//freopen("input.txt","w",stdout);
int a,b;
a=rand()%100+1,b=rand()%100+1;
printf("%d %d\n",a,b);
return 0;
}
然后你根据这三个个cpp生成三个个exe,然后放入那个对拍文件夹里
然后,
方法一(这个比方法二运行起来更快一点):
新建一个 对拍bat版.txt
输入:
:again data > input.txt biaoda < input.txt > biaoda_output.txt test < input.txt > test_output.txt fc biaoda_output.txt test_output.txt if not errorlevel 1 goto again pause
把扩展名txt改为bat,当然要保证这个bat文件也在对拍文件夹下,使用时运行这个bat就可以
方法二:
这是一段cpp代码,对拍exe版.cpp:
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
//int t=200;
while(1)
{
// t--;
system("data*ex.e** > data.txt");
system("biaoda*ex.e** < data.txt > biaoda.txt");
system("test*ex.e** < data.txt > test.txt");
if(system("fc test.txt biaoda.txt")) break;
}
if(t==0) cout<<"no error"<<endl;
else cout<<"error"<<endl;
//system("pause");
return 0;
}
根据这个,生成一个 对拍exe版*ex.e**,然后这个exe也要放在对拍这个文件夹下,然后使用时运行这个exe就行
当然,假如你有dev-cpp这个编译器的话,就很快,因为它可以直接编译cpp文件或者c文件,然后在同一个文件夹下生成对应的exe文件,然后这样就很方便啦,希望能对大家有所帮助。
名校降分有“套路”
2003年开始的高校自主招生演变到今天,已经不是只涉及到少数考生的事情了。特别是从2010年开始出现自主招生联盟统考以来,每年被卷入的考生越来越多。被称之为“小高考”。
2015年自主招生选拔考核挪到高考之后进行,自主招生联盟统考方式也随之取消。这一变化所引起的一系列的变化必将影响到考生。而2015年高考加分在2014年瘦身的基础上再一次更大范围和更大力度的瘦身,这使得自主招生成为高考录取前最重要的获得加分的途径。再加上教育部对高校自主招生名额的限制更加严格,2017年之后自主招生的竞争更加惨烈。
各个高校自主招生的门槛不一,但报名要求却有一定的规律。首先是对学业成绩要求。自主招生中学习成绩很重要,考生和家长不要以为高校招的是“偏才”和“怪才”。高校通常会要求学生提供中学平时成绩,包括高一、高二重要考试的成绩,不仅有绝对分数,还要有在班级或者年级的排名,从而综合评价考生的学习能力是否达到要求。其次是对竞赛获奖要求。一类是五大类学科竞赛,就是数学、物理、化学、信息科学、生物科学的全国竞赛或省级赛区竞赛。这与教育部对保送生资格界定要求的学科竞赛一致,只是高校的成绩要求相对低一些,比如获得全国三等奖以上,或者省、市的一、二等奖。另一类是非学科综合能力竞赛,比如创新大赛、创业大赛、才艺竞赛、辩论赛、演讲赛、作文竞赛、技能大赛等。这些竞赛可以反映学生的综合素质,也受到高校的重视。
燕博园专注自主招生和五大学科竞赛,我们拥有强大的师资力量、多年的竞赛经验以及各种丰富的线上线下课程,朝阳、通州、海淀、昌平四大校区任您选择。十一竞赛、自招集训营开营在即,欢迎大家【点击了解】。如果您想在家中学习学科竞赛的话也可以扫描下方二维码进入腾讯课堂学习。