如何快速的写出对拍程序

可以配合如何优雅的造数据食用qwq。

前言

  • 什么是对拍?

通俗来讲就是,你写了一份的正解,但是你不知道这个正解对不对,代码有没有写挂。

通常情况下你可能会考虑手造几个样例跑一跑试试。

但手造样例有时候又太弱,于是我们采用另一种方式。

你手写一个暴力。暴力的正确性肯定有保证对吧。

然后你写一个随机数据生成器,生成多组数据,同时运行暴力和正解,比较他们的输出结果是否相同,来反向证明正解有没有写挂。

然后这个过程就叫对拍。

  • 怎么写?

据我所知有两种形式,一种是在文本文档编辑,.bat 类型的对拍。

另一种是直接用 C++ 写的对拍。

接下来我们主要介绍第二种,用起来对我们会方便一些。

第一步:放入要验证的程序和暴力

找到自己的暴力和yy的正解, 分别放入std和test两个cpp中
(以 A + B Problem 为例)

#include <iostream>  
using namespace std;    

int main()  
{   
    freopen("in.in","r",stdin); // 读入生成的随机数据
    freopen("std.out","w",stdout);//这里是 std 的输出文件
    int a,b;    
    cin >> a >> b;   
    cout << a+b << endl;   
    return 0;    
} 
#include <stdio.h>  

int main()   
{  
    freopen("in.in","r",stdin); // 读入生成的随机数据
    freopen("test.out","w",stdout);//这里是自己写的暴力的输出文件
    int a, b;  
    scanf("%d %d",&a, &b);  
    printf("%d\n", a+b);  
    return 0;  
} 

第二步:造出随机数据

然后写一个用来创造随机数据的cpp,起名为 data (起名不重要

#include<cstdio>
#include<cstdlib>
#include<ctime>
int main()
{
    freopen("in.in","w",stdout); //创建一个 in.in 文本文档来存放我们的随机数据
    srand(time(0));
//  这是一个生成随机数随机种子,需要用到 ctime 库
//  这句话会保证每次的数据都是随机的。如果不加,每次调用相同的种子,生成的数据是不变的。
    printf("%d %d\n",rand(),rand());
//  这样就生成了我们需要的输入样例
    return 0;
}

第三步:进行文本对比

然后使用下面这个对拍程序

如果测试多组数据后程序仍然没有退出,恭喜,您的正解很可能是对的

如果测试几组数据后程序会停止运行,并会反馈两个输出不一样的地方。

此时关掉正在运行的窗口,打开in.in文件,就可以查看Hack数据了。

#include<bits/stdc++.h>
#include<cstdio>
#include<cstdlib>
#include<ctime>
using namespace std;
int main()
{
  int T = 0;
    while(1)  {//一直循环,直到找到不一样的数据
        cout << ++T;//可以加一个计数器
        system("data.exe");// 运行 data.exe,生成数据
        system("test.exe");// 运行test.exe,跑一边正解,得到正解的输出结果
        system("std.exe");// 运行std.exe,跑一边暴力,得到暴力的输出结果
        if(system("fc std.out test.out")) 
//      这个语句的实际意思就是比较 std.out 和 test.out 的内容是否相同
//      当 fc 返回 1 时,说明这时两个输出不同,返回值为 true
        break; //不一样就跳出循环
    }
    return 0;
}	

有什么问题欢迎提出。

鸣谢

感谢 Imy_bisLy 提供的技术与资源支持

posted @ 2021-02-16 09:33  Suzt_ilymtics  阅读(540)  评论(4编辑  收藏  举报