CSP-J/S对拍技巧(仅针对 2023 年的浙江 CSP-J/S 有一定参考意义)

本说明仅针对 2023 年的浙江 CSP-J/S 有效。事实上这个是作者的一个追忆版本。所以仅用作参考。

2023 年 浙江 CSP-J/S 复赛的windows环境是 windows 10,而且还配套有很多软件以及 python 3。

这里仅针对 windows 10 版本进行说明(但是也不保证一定能对)。

所以希望大家仅作参考,因为真不保证今年的比赛也是可以这么做的。仅做学习和参考用途,真不一定和实际环境一样。

正文

首先,我这里新建了一个名为 对拍 的文件夹,并且在 对拍 文件夹下建了一下文件(或文件夹):

  • tle.cpp:对拍程序(跑的比较慢但是数据肯定没问题的C++源文件)
  • std.cpp:提交程序(准备正式提交但是不确定对不对的程序,需要通过对拍进行测试)
  • gen.cpp:用于生成输入数据的程序(用于生成测试数据的C++源程序)
  • duipai.py:用于对拍的python脚本
  • data/ 文件夹

tle.cpp 和 std.cpp

这里为了方便测试,tle.cpp 输入一个整数 a,输出 a;而 std.cpp 输入一个整数 a,在 a 是 3 的倍数时输出 a+1,其他情况下输出 a。

tle.cpp

#include <bits/stdc++.h>
using namespace std;

int main() {
    int a;
    cin >> a;
    cout << a << endl;
    return 0;
}

std.cpp

#include <bits/stdc++.h>
using namespace std;

int main() {
    int a;
    cin >> a;
    printf("%d\n", a % 3 == 0 ? a + 1 : a);
    return 0;
}

gen.cpp

取名为 gen.cpp 主要是用于生成数据。其中:

  • xxx.in 输入数据
  • xxx.ans 通过运行 tle.cpp 编译成的 tle.exe 得到的正确数据
  • xxx.out 通过运行 std.cpp 编译成的 std.exe 得到的测试数据

注:编译运行 gen.cpp 前请建好 data/ 文件夹。

主函数中有 \(3\) 部分:

  • \(1\) 部分用于生成 xxx.in (使用前需要先注释掉第 \(2\)\(3\) 部分)
  • \(2\) 部分用于生成 xxx.ans(使用前需要先注释掉第 \(1\)\(3\) 部分)
  • \(3\) 部分用于生成 xxx.out(使用前需要先注释掉第 \(1\)\(2\) 部分)

如果要多次测试同一组数据,第二次运行前可以注释掉第 \(1\)\(2\) 部分(这样只会更新 xxx.out 文件)。

gen.cpp

#include <bits/stdc++.h>
using namespace std;
mt19937 rng(time(0));

int NUM = 50; // NUM 对应的是需要测试的数据组数,可以修改

// 封装一个函数用于返回 [l, r] 范围内的随机整数
int random(int l, int r) {
    return rng() % (r - l + 1) + l;
}

// 封装一个用于产生输入数据的函数
void gen_data(int t) {  // 这里的 t 对应的第几组测试数据,即 t.in
    cout << random(1, 1000) << endl;
}

int main() {
    for (int i = 1; i <= NUM; i++) {

        string filename;

        // 第 1 部分:产生 .in 文件
        filename = "data/" + to_string(i) + ".in";
        freopen(filename.c_str(), "w", stdout);
        gen_data(i);

        // 第 2 部分:产生 .ans 文件
        filename = "data/" + to_string(i) + ".in";
        freopen(filename.c_str(), "r", stdin);
        filename = "data/" + to_string(i) + ".ans";
        freopen(filename.c_str(), "w", stdout);
        system("tle.exe");

        // 第 3 部分:产生 .out 文件
        filename = "data/" + to_string(i) + ".in";
        freopen(filename.c_str(), "r", stdin);
        filename = "data/" + to_string(i) + ".out";
        freopen(filename.c_str(), "w", stdout);
        system("std.exe");
    }
    return 0;
}

duipai.py

数据都生成好了,所以最后是用于对拍的 duipai.py 程序。

2023年浙江复赛的 windows 环境中提供了很多可以打开 py 文件的程序,比如 vs code。

随便打开一个然后运行如下程序:

duipai.py

import os

NUM = 50

for i in range(1, NUM+1):
    cmd = f'fc data\{i}.ans data\{i}.out'
    s = os.popen(cmd).read()
    if 'FC: 找不到差异' in s:
        print(f'data {i} : ok')
    else:
        print(f'data {i} : different')
        print('是否显示详情? y(是): n(否)', end='')
        t = input().strip()
        if t == 'y':
            print(s)
        print('以上是所有信息,按回车继续……')
        input()

如果你觉得有点繁琐,那么以下是 duipai.py 的简化版本:

duipai.py(简化版)

import os

NUM = 50

for i in range(1, NUM+1):
    cmd = f'fc data\{i}.ans data\{i}.out'
    s = os.popen(cmd).read()
    if 'FC: 找不到差异' not in s:
        print(f'第 {i} 组测试数据不同')
        exit(0)
print('all same')

C++ 对拍程序

duipai.cpp

#include <bits/stdc++.h>
using namespace std;

const int NUM = 50;

int main() {

    for (int i = 1; i <= NUM; i++) {
        char ch[100];
        sprintf(ch, "fc data\\%d.ans data\\%d.out", i, i);
        auto result = system(ch);
        cout << result << endl;
    }

    return 0;
}
posted @ 2024-10-22 01:28  quanjun  阅读(46)  评论(0编辑  收藏  举报