本文主要是介绍信息学竞赛对拍器的设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
下面的内容是我很久以前写的,内容冗长,不怎么实用,比较简洁的代码请参考:
1.对拍器
2.数据生成器
信息学竞赛中,很多时候我们需要检验需要提交程序的正确性,但手动测试有太慢而且不准确。
所以我们可以写两个程序,一个用于提交,另一个测试(通常是比较正确但是往往用暴力写的,会超时),
当然写对拍器之前要写数据生成器,以后介绍,这是最简单的A+B Problem的数据生成器:
#include<bits/stdc++.h>
using namespace std;
int main(){freopen("in.txt","w",stdout);//请根据需要自行修改数据生成代码 int a,b;srand(time(0));a=rand();b=rand();printf("%d %d",a,b);return 0;
}
对拍器就是用于测试数据并比较两程序的输出是否相同的程序,下面介绍对拍器的写法:
方法一:
代码如下(程序B):
@echo off
set cnt=0
for /l %%i in (1,1,10) do (
::相当于for(int i = 1;i <= 10;i++) ,可以修改第三个数字来改变测试次数randdata.exestd.exemine.exefc out1.txt out2.txt >result.txtif errorlevel 1 ( ::如果发现不一致set cnt=1echo %%i:UnAccepted!pause)if not errorlevel 1 echo %%i:Accepted!
)
if %cnt%==0 color a && echo *** Totally Accepted! ***
if %cnt%==1 color c && echo *** Not All Accepted! ***
pause
以上代码是批处理写的,有兴趣的可以学习一下,还是有用的
讲代码拷贝到记事本,然后保存为 xxx.bat 或 xxx.cmd (xxx为文件名),就可以运行了
但是需要遵守以下规则:
I.使用程序A或B每个程序需要添加的语句:
a.你的程序:
1.需要把程序名称改为mine.cpp
2.添加到main函数开头:
freopen("in.txt","r",stdin);
freopen("out1.txt","w",stdout);
b.标准程序(或暴力正确程序)
1.把程序名称改为std.cpp
2.添加到main函数开头:
freopen("in.txt","r",stdin);
freopen("out2.txt","w",stdout);
还有另一种写法(程序C):
@echo off
set cnt=0
for /l %%i in (1,1,10) do (randdata.exestd.exe < in.txt > out1.txtmine.exe < in.txt > out2.txtfc out1.txt out2.txt > result.txtif errorlevel 1 (set cnt=1echo %%i:UnAccepted!pause)if not errorlevel 1 echo %%i:Accepted!
)
if %cnt%==0 color a && echo *** Totally Accepted! ***
if %cnt%==1 color c && echo *** Not All Accepted! ***
pause
II.使用程序C需要把freopen语句注释掉,程序名称同I
方法二:
先说方法二的优缺点:程序A界面比B稍友好一些,但有时会判断错误
代码如下(程序A):
on error resume next '忽略所有错误
set obj=createobject("wscript.shell")
set fso=createobject("scripting.filesystemobject")
dim ct,result,cnt
cnt=0
ct=inputbox("请输入需要测试的次数:","提示")
if ct>40 thenct=40msgbox"测试次数不能大于40,自动改为40次",vbinformation,"提示"
end if
for i=1 to ctobj.run"randdata.exe",true '启动数据生成程序obj.run"std.exe",true '启动标准程序(或暴力但准确性可以保证的程序)obj.run"mine.exe",true '启动你的程序obj.run"datacmp.exe",true '启动对比程序set fread=fso.opentextfile("result.txt",1)result=fread.readall '记录测试结果fread.closeif result<>"0" then '发现错误msgbox"发现错误:第" & i & "次测试" & chr(13) & "错误行数:" & result ,16,"提示"cnt=cnt+1end if
next
obj.run"taskkill -f -im std.exe"
obj.run"taskkill -f -im mine.exe"
obj.run"taskkill -f -im datacmp.exe"
msgbox"测试完毕!" & chr(13) & "共发现" & cnt & "处错误" ,,"结果"
程序CMP:
#include<bits/stdc++.h>
using namespace std;
char x[100],a1[100005][100],a2[100005][100];//可以根据需要修改数组大小
int main()
{freopen("result.txt","w",stdout);freopen("out1.txt","r",stdin);int i=0,j=1,sum=0;while(gets(x)!=0){int len=strlen(x);if(x[len-1]==' ') x[len-1]='\0';//忽略行尾空格 i++;strcpy(a1[i],x);}freopen("out2.txt","r",stdin);i=0;while(gets(x)!=0){int len=strlen(x);if(x[len-1]==' ') x[len-1]='\0';//忽略行尾空格 i++;strcpy(a2[i],x);}for(j=1;j<=i;j++)if(strcmp(a1[j],a2[j])!=0){
//查看错误行内容
// printf("error on line %d:\n",j);
// printf("\tcmp:%s\n\tstd:%s\n",a1[j],a2[j]);sum++;}cout<<sum;return 0;
}
同样,程序A用记事本打开,保存为xxx.vbs,程序CMP保存为datacmp.cpp,程序A注释比较详尽,就不多讲了
附:
友情提示:考试时需要自己写对拍器,因此建议读者记忆并能熟练编写数据生成器和对拍器(以下是最简单,也是最实用的版本)
@echo off
for /l %%i in (1,1,10) do (randdata.execode1.exe < in.txt > out1.txtcode2.exe < in.txt > out2.txtfc out1.txt out2.txt > result.txtif errorlevel 1 echo %%i:WA! && pauseif not errorlevel 1 echo %%i:AC!
)
pause
效果图:
效果图(程序C):
程序A:
这篇关于信息学竞赛对拍器的设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!