在算法竞赛中,我们常用对拍来初步检验程序。
网上也有其它的关于对拍的教程,但是任性的我还是要自己写一篇教程。
首先,我们要知道我们是用一个叫做” 批处理文件(.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 }