嘘~ 正在从服务器偷取页面 . . .

linux及windows对拍程序 C++


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 std
#### C++对拍程序
#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种)

对拍程序的思想简单,实现多样

在竞赛中能有所帮助


文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录