linux及windows对拍程序 C++
前言
OI赛制的比赛中,选手不能看到自己的成绩,那么如何保证代码正确呢?
1.水品高 秒切
2.暴力+对拍 尝试调正解
本文给出了linux和windows的对拍程序
一、什么是对拍?
在比赛中,某道题已经写出了暴力解法(须保证正确),开始尝试写正解
我们就可以用到对拍程序,用于对比暴力解法和尝试解法的输出结果,以判断该解法的是否是正解
注:暴力解法通常跑不了很大的点,因此对拍时数据不强,即使正确也未必是正解
那么对拍程序怎么写呢?
二、怎么写对拍程序?
对拍程序的写法有很多种,但结构基本一致
while(1)//不一定要用死循环
{
	生成随机数据
	暴力解法跑一遍
	尝试解法跑一遍
	比对
}接下来,我将以A+B Problem为例
首先,写暴力程序std.cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define R register
#define FILE
signed main()
{
#ifdef FILE
    freopen("data.in","r",stdin);
    freopen("std.out","w",stdout);
#endif
    int a,b;
    scanf("%lld%lld",&a,&b);
    while(b){a++,b--;}
    printf("%lld\n",a);
    return 0;
}接下来,尝试写正解
my.cpp#include<bits/stdc++.h>
using namespace std;
#define int long long
#define R register
#define FILE
signed main()
{
#ifdef FILE
    freopen("data.in","r",stdin);
    freopen("my.out","w",stdout);
#endif
    int a,b;
    scanf("%lld%lld",&a,&b);
    printf("%lld\n",a+b);
    return 0;
}然后,随机数生成器rand.cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define R register
#define mod (int)1e5
inline int Rand()
{
    //rand()随机数函数
    return ((rand()%mod*rand()%mod)%mod+rand())%mod;//这里可以随便些,反正生成随机数
}
signed main()
{
    srand(time(0));
    freopen("data.in","w",stdout);
    printf("%lld %lld\n",Rand(),Rand());
    return 0;
}最后,记得要把这些文件都编译哦!
注:需要有可执行文件才能对拍,因此需要编译
1.linux下的对拍程序
linux下的比对命令是diff./std的意思可以简单地认为是运行当前目录下std.cpp编译后生成的可执行文件std
本人使用的是vscode,编译后生成的可执行文件就是文件名
注:如果您没有用类似的软件,您可以手动编译
cd code 注:该文件所在目录,我的叫code
g++ std.cpp -o stdC++对拍程序
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define R register
int i=0;
signed main()
{
    while(1)
    {
        system("./rand");//这些文件要和checker.cpp放在一个目录下
        system("./std");//直接运行,因为已经写了freopen
        system("./my");
        printf("Running on test %lld\n",++i);
        if(system("diff std.out my.out"))//如果相同(即正确)返回0
        {
            printf("Wrong Answer on test %lld\n",i);
            return 0;
        }
    }
    return 0;
}Bash脚本
#!/bin/bash
i=0
while true
do
    i=$(($i+1))
    ./rand
    ./std
    ./my
    echo "Running on test $i"
    if !(diff std.out my.out);then
        echo "Wrong answer on test $i"
        break
    fi
done注:可以用以下指令编辑.sh文件
cd code 注:该文件所在目录
gedit checker.sh 注:新建文件
sh checker.sh 注:运行2.windows下的对拍程序
本人使用的Dev C++
C++对拍程序
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define R register
int i=0;
signed main()
{
    while(1)
    {
        system("rand.exe");//直接运行,因为已经写了freopen
        system("std.exe");
        system("my.exe");
        printf("Running on test %lld\n",++i);
        if(system("fc std.out my.out"))//windows下的比对命令是fc
        {
            printf("Wrong Answer on test %lld\n",i);
            return 0;
        }
    }
    return 0;
}bat脚本
@echo off
::指不显示命令
set /a i=0
:loop
::设置一个标签
rand.exe
std.exe
my.exe
set /a i+=1
echo Running on test %i%
fc std.out my.out
if %errorlevel%==0 goto loop
::没有问题回到loop那
echo Wrong answer on test %i%
::否则退出
pause
^C总结
本文介绍了linux和windows下对拍程序的写法(共4种)
对拍程序的思想简单,实现多样
在竞赛中能有所帮助
