在算法竞赛中,我们常用对拍来初步检验程序。
网上也有其它的关于对拍的教程,但是任性的我还是要自己写一篇教程。
首先,我们要知道我们是用一个叫做” 批处理文件(.bat)“的东西来处理这个问题。点击初步了解bat
不过不必深究这个,因为我们只用其中一小部分。
那么,我的基本思路是:
①先得到测试数据及答案(可用符合题意的随机数程序);
②打开标准程序(或你的暴力程序)和你的程序并生成答案;
③比较文件,一致则循环比较,否则输出文件不同点;
当然,你可以添加一些功能,如:综合时间和正确率给程序评分等(我就懒得写了)。
先用一个例子来示范一下
就用2016年noip第一天的第一题, 点击查看题目
接着写我们的bat文件了(建议比赛开场前时写)
实所谓的批处理文件,就是把DOS命令先写下来。所以,就用记事本写就行,然后后缀改成.bat。点击了解怎么改后缀
我写的bat:
@echo off ::关回显,不必深究 :sign ::标识符,与C语言的用法大致一样
rand ::一个用于生成输入文件的随机数程序 biggodsans ::执行大神与我的程序 myans fc biggodsans.out myans.out ::比较文件 if errorlevel 0 goto sign ::如果文件一样的话就跳转回sign处继续处理,否则将在屏幕显示错误信息(该行一定要连一起写)
其实重点在第六行,这个bat就是用来检验你的答案是否和标准答案完全一致(如有格式要求的题目)。
所以,只写一行也行。
用两个测试数据说明问题。点击获取测试数据
修改一下文件名,简单测试文件比较
@echo off
fc biggodsans.out myans.out
pause ::可能会一闪而过,起暂停屏幕作用
用toy6.in所得结果
用toy16.in得到错误信息
它会显示不同处的上下文(我这里是程序没有输出)
大概就是这样了
一个华丽的分割线,以下是我和大神的代码
我的代码是()
1 #include<cstdio> 2 #include<iostream> 3 #include<string> 4 using namespace std; 5 string name[100006]; 6 bool inorout[100006]; //第i个小人的朝向,false表示向内 7 int n,m; 8 int i,j,ai,si; 9 int nowp=1; 10 int main() 11 { 12 freopen("toy.in","r",stdin); 13 freopen("myans.out","w",stdout); 14 scanf("%d%d",&n,&m); 15 for(i=1;i<=n;++i) 16 { 17 scanf("%d",&j); 18 inorout[i]=(j==0?false:true); 19 cin>>name[i]; 20 } 21 while(m--) //就是一个简单的模拟 22 { 23 scanf("%d%d",&ai,&si); 24 if(inorout[nowp]==(bool)ai) nowp=nowp-si+n; //显然朝向和向左右数有关 25 else nowp+=si; 26 nowp=nowp%n; //注意:它是个圈!!! 27 } 28 cout<<name[nowp]; 29 return 0; 30 } 31
我以为我完全正确。然而,我得了90分...
我终于知道题目里的mengbier是谁了
比赛后我找到大神的答案
1 #include<cstdio> //大神的代码,膜拜ing... 2 const int N=1e5+5,L=11; 3 int n,q,i,a[N],x; 4 char s[N][L]; 5 int read(){ 6 char c=getchar();int k=0;for (;c<48||c>57;c=getchar()); 7 for (;c>47&&c<58;c=getchar()) k=(k<<3)+(k<<1)+c-48;return k; 8 } 9 int main(){ 10 freopen("toy.in","r",stdin); 11 freopen("biggodsans.out","w",stdout); 12 for (n=read(),q=read(),i=0;i<n;i++){ 13 a[i]=read();scanf("%s",s[i]); 14 } 15 for (x=0;q--;){ 16 int opt=read()^a[x],k=read(); 17 if (opt) x=(x+k)%n; 18 else x=(x-k+n)%n; 19 } 20 printf("%s",s[x]); 21 }