在信息学竞赛中,尤其是考试的时候,经常会出现把水题写水的情况,而题目那一两个单薄的测试数据常常不足以让我们发现自己程序中的BUG。在竞赛时,水题悲剧了的话下场一定会很惨。在这种情况下,我们可以采用写一个对拍程序的方法来大大降低出错的可能。
基本思路 是对于一道题目来讲,写出高效算法后,时间充裕的情况下再写一个纯暴力的算法,写一个数据生成器,对你的程序和暴力程序的结果进行比对,出现错误后就人工 检查。一般来讲数据范围一开始可以小一点,小数据过了以后再慢慢扩大,为保证正确性你在写下一题的时候可以让对拍程序一直跑着。
这里的关键是要写一个批处理让Windows不停地反复执行这一操作,代码如下。
1 @echo off 2 :loop 3 datamaker 4 std 5 myprogram 6 fc myprogram.out std.out 7 if not errorlevel 1 goto loop 8 pause 9 go to loop
在文本文档中写好以后,扩展名保存为bat即可直接运行。
简单解释:
datamaker #数据生成器,生产随机数据到myprogram.in
std #纯暴力标准程序,从myprogram.in读入数据,运行后输出标准答案到std.out
myprogram #高效程序,即你最终要提交的程序,从myprogram.in读入数据,运行后输出标准答案到myprogram.out
对拍指的是用一个简单的程序去检测一个复杂的程序。
具体的方法就是:
1、随机生成n组数据。
2、用复杂的程序把数据跑一遍。(因为你要检查的就是这个程序,可能会有小漏洞,用这个可以检查出来)。
3、用简单的程序把数据跑一遍。(简单的程序不要错就行了)
4、对比两次的答案,如果不一样,你就要检查自己的程序了。
ACM的程序怎么设置对拍程序??有没有那个好心人给我和例子吧,
基本思路是对于一道题目来讲,写出高效算法后,时间充裕的情况下再写一个纯暴力的算法,写一个数据生成器,对你的程序和暴力程序的结果进行比对,出现错误后就人工检查。一般来讲数据范围一开始可以小一点,小数据过了以后再慢慢扩大,为保证正确性你在写下一题的时候可以让对拍程序一直跑着。
这是别人说的,可是那个数据生成器和高效程序和暴力程序都是什么啊?不明白。
有完整例子可以加分。。
---------------------对拍程序介绍,来自百度-----------------------------------------
在信息学竞赛中,尤其是考试的时候,经常会出现把水题写水的情况,而题目那一两个单薄的测试数据常常不足以让我们发现自己程序中的BUG。在竞赛时,水题悲剧了的话下场一定会很惨。在这种情况下,我们可以采用写一个对拍程序的方法来大大降低出错的可能。
基本思路是对于一道题目来讲,写出高效算法后,时间充裕的情况下再写一个纯暴力的算法,写一个数据生成器,对你的程序和暴力程序的结果进行比对,出现错误后就人工检查。一般来讲数据范围一开始可以小一点,小数据过了以后再慢慢扩大,为保证正确性你在写下一题的时候可以让对拍程序一直跑着。
这里的关键是要写一个批处理让Windows不停地反复执行这一操作,代码如下。
对拍程序的写法 如下
@echo off
:loop
datamaker #数据生成器 rand.exe > data.in 这里的大于符号,小于符号为重定向符号
std #标准程序 std.exe < data.in > std.out
myprogram #my.exe < data.in > my.out 我的程序
fc ans.out std.out //比较两个程序的输出是否一致,一致则返回0
if not errorlevel 1 goto loop
pause
goto loop
#最后上边的 内容 保存为.bat文件
#rand.exe std.exe my.exe 以及windows下的这个 .bat文件放在同一个目录下
***************************************************************************************************
这里数据生成器: 就是你自己编写一个应用程序 rand.exe,这个应用程序就是随机的生成一组符合题意的输入数据并存放到上边提到的 输入数据文件中data.in
高效程序:就是上边提到的 高效算法 写的程序,即 my.exe
暴力程序 :就是指能够保证所有输入数据都能输出正确结果的 程序,即这里的std.exe
上边的.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.exe可执行文件 然后在批处理文件中 直接调用 rand.exe>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.exe可执行文件 然后在批处理文件中 直接调用 std.exe<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.exe可执行文件 然后在批处理文件中 直接调用 my.exe<data.in>std.out即将从data.in中获取输入,然后将输出结果重定向到my.out文件中
批处理文件 test.bat 内容如下
@echo off
:loop
rand.exe>data.in
std.exe<data.in>std.out
my.exe<data.in>my.out
fc my.out std.out
if not errorlevel 1 goto loop
pause
goto loop
最后将这三个.exe文件和批处理文件放到同一个目录下 运行批处理文件即可