线段树对拍程序

用前须知:

需将python程序和待测试cpp程序放在同一级目录下(该程序使用相对路径),否则会报错,无法编译!

测试前需要将generate_test_data函数中的输入自行更改。

专为线段树定制的对拍程序

import random
import subprocess

# 编译 C++ 程序
def compile_cpp(file_name, output_name):
    result = subprocess.run(["g++", file_name, "-o", output_name], capture_output=True, text=True)
    if result.returncode != 0:
        print(f"Compilation failed for {file_name}:\n{result.stderr}")
        return False
    return True

# 运行程序,输入 `input_data`,返回程序输出
def run_program(executable, input_data):
    try:
        result = subprocess.run(
            [f"./{executable}"],
            input=input_data,
            capture_output=True,
            text=True,
            timeout=5  # 超时时间,避免死循环
        )
        return result.stdout.strip(), result.returncode
    except subprocess.TimeoutExpired:
        return "Timeout", -1

# 生成测试数据
def generate_test_data():
    n = random.randint(5, 1000)  # 数组长度
    m = random.randint(10, 10000)  # 操作次数
    arr = [random.randint(10, 10000) for _ in range(n)]
    ans = []    # 答案数组
    lst = arr[:]    # 暴力更新答案数组
    operations = [] # 操作输入

    while m > 0:
        m -= 1
        op = random.randint(0, 2)
        x = random.randint(1, n)
        y = random.randint(x, n)

        if op == 0:
            k = random.randint(10, 10000)
            operations.append(f"{op} {x} {y} {k}")
            for i in range(x - 1, y):
                lst[i] += k
        if op == 1:
            k = random.randint(10, 10000)
            operations.append(f"{op} {x} {y} {k}")
            for i in range(x - 1, y):
                lst[i] = k
        elif op == 2:
            operations.append(f"{op} {x} {y}")
            total = sum(lst[x - 1:y])
            ans.append(total)

    # 按格式拼接输出
    arr_str = " ".join(map(str, arr))
    operations_str = "\n".join(operations)
    input_data = f"{n} {len(operations)}\n{arr_str}\n{operations_str}"
    return input_data, ans

if __name__ == "__main__":
    name = input('输入cpp程序名称, 默认为"a": ')
    if name == "":
        name = "a"
    cpp_file = name + ".cpp"  # C++ 文件名
    exe_file = name + "_exe"  # 编译后的可执行文件名

    # 编译 C++ 程序
    if not compile_cpp(cpp_file, exe_file):
        exit(1)

    # 运行对拍
    time = 0
    times = int(input("输入测试数据组数: "))
    for test_case in range(1, times + 1):
        input_data, expected_ans = generate_test_data()  # 生成测试数据
        # print(f"Test Case #{test_case}:\nInput:\n{input_data}")   // 数据展示开关

        # 运行程序
        output, ret_code = run_program(exe_file, input_data)

        # 检查程序运行是否成功
        if ret_code != 0:
            print(f"Error: Program crashed with return code {ret_code}.")
            break

        # 将程序输出与 Python 生成的正确答案对比
        time += 1
        output_list = list(map(int, output.split()))
        if output_list != expected_ans:
            print("Output does not match the expected answer ❌")
            print(f"Expected:\n{expected_ans}")
            print(f"Output:\n{output_list}")
            break
        else:
            print("Output matches the expected answer ✅")
    if time == times:
        print("共测试%d组测试, 预期测试%d组测试, 全部通过!!" % (time, times))
    else:
        print("共测试%d组测试, 预期测试%d组测试, 未通过" % (time, times))

线段树对拍程序
http://linyisu.github.io/2025/01/22/杂项/线段树对拍程序/
作者
linyisu
发布于
2025年1月22日
许可协议