ACM/XCPC对拍(Linux/Windows)

前言

心血来潮,整理一手c++对拍,分别是Linux下的脚本对拍和windows下的代码对拍

Windows对拍

windows下的对拍总共三个文件分别是正解(ok.cpp)错解(bad.cpp)和对拍生成数据的文件,对拍的时候只需要运行生成数据文件(beat.cpp)即可。下面给出三个文件示例代码
正解示例代码:ok.cpp

#include <bits/stdc++.h>
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int a, b;
    std::cin >> a >> b;
    std::cout << a + b << "\n";
}

错解示例代码:bad.cpp

#include <bits/stdc++.h>
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int a, b;
    std::cin >> a >> b;
    if (rng() % 10 >= 1) {
        std::cout << a + b << '\n';
    } else {
        std::cout << a + b + 1 << '\n';
    }
}

对拍示例代码:beat.cpp
.\beat是我的对拍存放的目录,可以自行更改,如果存放在你当前开的文件夹下面,代码中的.\beat\都可以不打,默认运行当前文件。

#include <bits/stdc++.h>
int main() {
    #define COMPLILE // 是否重新编译,不需要重新编译注释掉就行了
    #ifdef COMPLILE
        system("g++ -std=c++2a .\\beat\\ok.cpp -o .\\beat\\ok.exe -O3");
        system("g++ -std=c++2a .\\beat\\bad.cpp -o .\\beat\\bad.exe -O3");
    #endif
    for (int i = 0; i < 1000000; ++i) {
        std::cout << "Testcase: " << i << '\n';
        {
            std::ofstream cout("in.txt");
            std::uniform_int_distribution<int> dist(2, 1e9);
            std::mt19937 mt(std::chrono::steady_clock::now().time_since_epoch().count());
            #define rng() dist(mt)
            // std::random_device rd;
            // #define rng() dist(rd)

            cout << rng() % 10 << ' ' << rng() % 10 << "\n";

            cout.close();
        }



        system(".\\beat\\ok.exe < .\\beat\\in.txt > .\\beat\\ok.txt");
        system(".\\beat\\bad.exe < .\\beat\\in.txt > .\\beat\\bad.txt");
        // getchar(); // 单步回车比较
        // system("fc .\\beat\\ok.txt .\\beat\\bad.txt")
        if (system("fc .\\beat\\ok.txt .\\beat\\bad.txt")) { // 自动比较 
            /* 是否将正确结果和错误结果输出在输入文件,方便查看,自行选择是否需要
            system("echo ok: >> .\\beat\\in.txt");
            system("type .\\beat\\ok.txt >> .\\beat\\in.txt");
            system("echo bad: >> .\\beat\\in.txt");
            system("type .\\beat\\bad.txt >> .\\beat\\in.txt");
            */
            puts("WA!!!");
            break;
        }
    }
}

最后放一个我的文件目录结构

Linux对拍

我的Linux对拍跟windows有点区别,我是使用脚本对拍同时也是用脚本运行文件(当然也可以跟windows一样使用文件对拍)。
下面先放一些linux常用指令, 方便后面对拍代码的理解

clear
功能:清理屏幕,Ctrl+l快捷键具有相同的功能

pwd
功能:显示当前所在的工作目录

cd <path>
功能:改变当前的工作目录

ls [参数] [路径]
功能:显示指定路径下有哪些文件,如果没有路径参数则显示当前工作目录下有哪些文件
 
man [n] <key> 查看系统的帮助手册
	
time <可执行文件> 
功能:执行一个程序,并记录该程序的执行时间
	real	0m0.015s 程序执行的总用时
	user	0m0.013s 用户态执行的时间
	sys		0m0.000s 内核态执行的时间
	real = user + sys + 用户态内存态切换消耗的时间

diff [选项] <可执行文件> <可执行文件>
逐行比较<各文件>。

touch <filename>
功能:创建新文件

rm <filename> 
功能:删除文件,删除的文件不经过回收站,而是直接从文件系统中删除,很难恢复,删除时要慎重

cp <src> <<path>/[filename]> 
功能:复制文件,可以在复制过程中给目标文件取个新名字

mv <src> <<path>/[filename]>
功能:移动文件,也可以在移动过程中给目标文件取个新名字,并且它还具有重命名的功能

cat <filename>
功能:查看文件内容,它会把文件的所有内容都输出到屏幕上,但不适合用来查看内容比较多的文件

mkdir <dirname>
功能:创建目录
	-p 可以创建多级目录

rm -rf <dirname>
功能:强制删除非空目录
	
cp -r <srcdir> <<path/>[dirname]> 
功能:直接使用cp复制目录默认会忽略,需要加上r参数

mv 在移动目录和重命名目录时,不需要加任何参数,直接使用即可

chmod
功能:修改文件权限
	用法1:chmod mmm <filename>
            每个 m = 4r 2w 1x 都由组成一共有8种情况
            0 ---   1 --x   2 -w-   3 -wx 
            4 r--   5 r-x   6 rw-   7 rwx
            第一m 对应前三个字符 文件的主人的权限(属主)
            第二m 对应中间三个字符 与文件的主人同一级用户的权限(属组)
            第三m 对应末尾三个字符 其它用户的权限
	用法二:chmod +/- r、w、x <filename> 所有用户一起增加或减少某一项权限。
    注意:目录文件需要执行权限才能进入,常用的两种权限:644普通文件,755目录文件

timeout [选项] 停留时间 命令 [参数]...
功能:运行指定命令,在指定的停留时间后若该命令仍在运行则将其中止。

code <filename>
功能:使用vsc打开文件,没有就创建

vi/vim <filename>
功能:使用vim打开文件,没有就创建

wc [参数] [路径]
功能:(字数统计)命令打印文件中的行数、字数和字节数。
	-l 只打印行数
	-w 只打印字数
	-c 仅打印字节数

下面介绍以下如何对linux的终端进行配置自定义命令,使得打的代码更短 。
1、在终端输入 sudo vim ~/.bashrc,按i进入插入模式,从最底行开始编辑
2、ESC进入命令模式,按:键输入wq保存并退出
​3、重新加载配置文件:source ~/.bashrc 实现精简命令提示信息的效果
下面是我的部分配置

alias g++='g++ -std=c++17'

mk() { #创建目录并进入
	mkdir $1 && cd $1
}
thsh() { #创建脚本并赋予权限,然后vsc打开
	touch $1 && code $1 && echo "#!/bin/bash" > $1 && chmod u+x *.sh
}
thcpp() { #创建cpp文件,并用vsc打开
	touch $1 && \
		echo "#include <bits/stdc++.h>" > $1 &&
		echo "int main() {" >> $1 &&
		echo "    std::cin.tie(nullptr)->sync_with_stdio(false);" >> $1 &&
		echo "}" >> $1  &&
		code $1
}
alias cu='cd ..' # 返回上级目录

最后是我的linux对拍脚本(如果没有权限则使用chmod -x beat.sh设置运行权限)
beat.sh 对拍文件
-std=c++2a-O3可以根据自己选择是否添加

#!/bin/bash
g++ -std=c++2a ok.cpp -o ok -O3
g++ -std=c++2a sol.cpp -o bad
g++ -std=c++2a gen.cpp -o gen
for tt in $(seq 1 100)
do
    echo ===== Testcase $tt =====
    ./gen > in
    timeout 1 ./ok < in > okout
    timeout 1 ./bad < in > badout
    diff -q -b okout badout
    if [[ $? != 0 ]]
    then
        echo \> ok 
        echo $(cat <okout)
        echo \> bad
        echo $(cat <badout)
        echo \> Example
        cat in
        ./ok < in > ans$(find in* | wc -l) # 创建错误样例正确结果文件
        cp in in$(find in* | wc -l) #将错误数据设置为最后一个.in
        break
    fi
done

gen.cpp 生成数据文件

#include <bits/stdc++.h>
std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
using std::cout;
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    cout << rng() % 10 << ' ' << rng() % 10 << '\n';
}

run.sh 运行文件
我这里运行的是a.cpp文件,linux如果不指定则会默认将编译结果储存在a.out 里面。

#!/bin/bash
g++ -std=c++2a sol.cpp

#运行所有测试点
for file in ./in*
do
    diff -q -b <(timeout 1 ./a.out < "$file") ans${file#*in}
    if [[ $? != 0 ]]
    then
        echo ===== Error ${file#*in} =====
        echo Test: 
        cat $file
        echo ok: 
        cat < ans${file#*in} 
        echo bad: 
        timeout 1 ./a.out < "$file" # 同行输出
    else
        echo ===== AC ${file#*in} =====
    fi
done

# 对拍错误样例
# echo ===== Test Case Error =====
# time ./a.out < in

# 手搓
# echo ===== My ===== 
# timeout 1 ./a.out

# 运行所有样例 并输出到对应的ans文件
# for file in ./in*
# do
#     echo "runing on ${file#*in}"
#     ./a.out < "$file" > ans${file#*in}
# done

最后的ac.cppbad.cpp和Windows一样就不贴了。然后依旧是附一张我的linux对拍目录结构

Makefile执行cpp

CXX := g++ # 编译器选项
CXXFLAGS = -std=c++2a # 编译器参数
OBJS = sol.cpp 
TARGET := sol # 此处添加最后生成的可执行文件名

all:$(TARGET)
	@./$^ <in1 

$(TARGET):$(OBJS)
	@(CXX) $(CXXFLAGS) -o $@ $^
	@rm -rf *.o

数据生成

最后放一下图和树的数据制造代码

{ // 随机生成图
    int n = rng();
    std::vector<std::pair<int, int>> h;
    std::vector<std::vector<int>> g(n + 1, std::vector<int>(n + 1));
    for (int i = 2; i <= n; ++i) {
        int x = rng() % (i - 1) + 1;
        g[x][i] = 1;
        h.emplace_back(x, i);
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = i + 1; j <= n; ++j) if (!g[i][j] && rng() % 2) {
            g[i][j] = 1;
            h.emplace_back(i, j);
        }
    }
    cout << n << ' ' << size(h) << "\n";
    for (auto [a, b] : h) {
        cout << a << ' ' << b << ' ' << rng() << "\n";
    }
}
{ // 随机生成树
    int n = rng();
    cout << n << '\n';
    for (int i = 2; i <= n; ++i) {
        cout << rng() % (i - 1) + 1 << ' ' << i << "\n";
    }
}
posted @   sleeeeeping  阅读(332)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
  1. 1 吹梦到西洲 恋恋故人难,黄诗扶,妖扬
  2. 2 敢归云间宿 三无Marblue
吹梦到西洲 - 恋恋故人难,黄诗扶,妖扬
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 颀鞍

作曲 : 铃木航海

编曲 : 远藤直弥/冯帆

制作人 : 冯帆/铃木航海

(妖扬)

(妖扬)

无何化有 感物知春秋

秋毫濡沫欲绸缪 搦管相留

(黄诗扶)

留骨攒峰 留容映水秀

留观四时曾邂逅 佳人西洲

(妖扬)

(妖扬)

西洲何有 远树平高丘

云闲方外雨不收 稚子牵牛

(黄诗扶)

闹市无声 百态阴晴栩栩侔

藤衣半卷苔衣皱 岁月自无忧

(妖扬)

(妖扬)

驾马驱车 尚几程扶摇入画中 咫尺

(黄诗扶)

径曲桥横 精诚难通

(黄诗扶、妖扬)

(黄诗扶、妖扬)

盼你渡口 待你桥头

松香接地走

挥癯龙绣虎出怀袖

起微石落海连波动

描数曲箜篌线同轴

勒笔烟直大漠 沧浪盘虬

一纸淋漓漫点方圆透

记我 长风万里绕指未相勾

形生意成 此意 逍遥不游

(妖扬)

(妖扬)

日月何寿 江海滴更漏

爱向人间借朝暮 悲喜为酬

(黄诗扶)

种柳春莺 知它风尘不可救

绵绵更在三生后 谁隔世读关鸠

(妖扬)

(妖扬)

诗说红豆 遍南国未见人长久 见多少

(黄诗扶)

来时芳华 去时白头

(黄诗扶、妖扬)

(黄诗扶、妖扬)

忘你不舍 寻你不休

画外人易朽

似浓淡相间色相构

染冰雪先披琉璃胄

蘸朱紫将登金银楼

天命碧城灰土 刀弓褐锈

举手夜古泼断青蓝右

照我 萤灯嫁昼只影归洪流

身魂如寄 此世 逍遥不游

(黄诗扶)

(黄诗扶)

情一物 无木成林无水行舟

情一事 未算藏谋真还谬

情一人 积深不厚积年不旧

情一念 墨尽非空 百代飞白骤 划地为囚

(妖扬)

(妖扬)

蓝田需汲酒 惟琼浆能浇美玉瘦

至高者清难垢 至贵者润因愁

痴竭火 知她不能求

醉逢歌 知他不必候

只约灵犀过隙灵光暗相投

(黄诗扶、妖扬)

(黄诗扶、妖扬)

万籁停吹奏

支颐听秋水问蜉蝣

既玄冥不可量北斗

却何信相思最温柔

顾盼花发鸿蒙 怦然而梦

你与二十八宿皆回眸

系我 彩翼鲸尾红丝天地周

情之所至 此心 逍遥不游

吉他 : ShadOw

钢琴 : ShadOw

和声编写 : 冯帆

和声 : 黄诗扶

人声混音 : 徐志明

混音 : 冯帆

母带 : 冯帆

企划 : 三糙文化

出品公司 : Negia Entertainment Inc.

点击右上角即可分享
微信分享提示