线段树对拍程序
用前须知:
需将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))