算法竞赛中在windows下的对拍

昨日听网课习得创建.bat文件进行大数据对拍一法,颇觉好用,现撰博客一篇于此——

bat文件

bat文件是dos下的批处理文件。批处理文件是无格式的文本文件,它包含一条或多条命令。它的文件扩展名为 .bat 或 .cmd。在命令提示下输入批处理文件的名称,或者双击该批处理文件,系统就会调用cmd.exe按照该文件中各个命令出现的顺序来逐个运行它们。使用批处理文件(也被称为批处理程序或脚本),可以简化日常或重复性任务。

想必dos这个东西大家都知道吧,bat文件其实就是将多条dos命令写成一个程序的样子,这样的话可以进行一些方便的操作,对拍就是其中之一

对拍

假设某人写了一个高效但不知道是否正确的程序A,他想验证这个程序的正确性,他就可以写一个低效但是正确率很高的程序B,给这两个程序同样的输入,比较这两个程序的输出即可
而对拍就是不停的重复上文的这一过程,直到你想让它停的时候
于是我们可以归纳出对拍的要素:

  • 待测程序A
  • 对拍程序B
  • 数据生成程序C
  • 对拍器

我们用对拍器让C不断的生成数据,让A,B运行这组数据,然后让对拍器比较A,B的输出,若一样,继续生成数据,否则退出对拍器,出问题的数据就会保存在C的输出到的文件里了,这个时候用这组数据来DGBUG再好不过了

这个对拍器应该是可以用c++来实现的,但是用批处理来写会更方便,也可以极大的规避对拍器出bug的风险(考场上对拍器写挂了的话会疯的

实现

这里我们以高精度A+B来举例

程序A (gaojing.exe)
某luogu远古神犇

#include<bits/stdc++.h>
using namespace std;
string a,b,c;
int main(){
    ios::sync_with_stdio(false);
    cin>>a>>b;
    int l=a.size(),q=b.size(),h,k=0;
    if(l>q) c=a,a=b,b=c,h=l,l=q,q=h; 
    for(int i=1;i<=q;++i){
        if(i<=l) h=a[l-i]-48;
        else h=0;
        c[i]=b[q-i]+h-48+k;
        if(c[i]>9){c[i]-=10;k=1;}
        else k=0;
    }
    if(k) cout<<1;
    for(int i=q;i>0;--i) cout<<(short)c[i];
    return 0;
}

程序B (baoli.exe)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
	ll a;ll b;
	scanf("%lld%lld",&a,&b);
	printf("%lld",a+b);
}

数据生成器C (radom.exe)

#include<bits/stdc++.h>
using namespace std;
int main() 
{
	srand( (unsigned)time( NULL ) );
	unsigned int a, b;
	a = (rand() << 16) + rand();
	b = (rand() << 16) + rand();
	a %= 100000;
	b %= 100000;
	cout << a << endl << b; 
	return 0;
}

对拍器

:loop
radom.exe > data.txt   
gaojing.exe < data.txt > ans1.txt  
baoli.exe < data.txt > ans2.txt 
fc /A ans1.txt ans2.txt
if not errorlevel 1 goto loop
pause
:end

解释一下这个对拍器
第一行是个标识符,就像c++里面的goto语句一样
第二行就是让数据生成器radom.exe生成一组数据,放在data.txt里
第三四行就是让程序A和B分别使用data.txt里面的数据来运行一次,结果分别放在ans1.txt和ans2.txt里面
第五行就是比较ans1.txt和ans2.txt里面的数据
第六行是一个判断语句,如果数据一样,就跳至标识符loop(第一行)如果不一样,就跳过这一句
第七八行就是结束的意思,当运行到这两句时,我们已经找到了一组反例数据,理应退出了

对拍时,我们将程序A,B,C编译好,将对拍器在txt文件里写好,写好保存后将后缀名.txt改为.bat即可
将这四个东西放在同一个文件夹下,然后点开对拍器程序,然后就会…

在这里插入图片描述

如果你的程序是正确的,它会一直跑,要停止的话按下ctrl+c,它会提示你是否停止批处理,键入y即可停止
若有误,它会这样
在这里插入图片描述

不一样的答案被显示了出来,出错的数据也被保留在了data.txt里面


update
蒟蒻发现用bat写的东西不好调试,又看了几个大佬的博客,才明白过来c++才是真正的归宿
对拍器c++版

#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
    while(1)
    {
        system("datamaker.exe > data.txt");
        system("code.exe < data.txt > 1.txt");
        system("duipai.exe < data.txt > 2.txt");
        if(system("fc 1.txt 2.txt"))   break;
    }
    return 0;
}

这下好多了,又可以调试又可以加自己的提示信息


update 2019/2/9
发现LRL大佬写的对拍更牛逼,现附地址于下

传送门
文毕——

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AndrewMe8211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值