CSP-J/S對拍技巧(僅針對 2023 年的浙江 CSP-J/S 有一定參考意義)

quanjun發表於2024-10-22

本說明僅針對 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')

相關文章