linux下对拍

· · 个人记录

鉴于NOI系列赛事在辣鸡NOI LINUX环境进行,特地对linux下对拍进行了一下学习。在此分享。

以下内容中的文件名解释:

一个熟练的C++选手

C++作为一个高级语言,可移植性本身就很好,所以这个方法对于所有平台通用。

只需要将以下程序和test、std放在一个目录内编译运行即可。

#include <bits/stdc++.h>

using namespace std;

void gen()
{ ... } //数据生成,下篇博文中具体介绍

int main()
{
    while(true) {
        gen();//也可以自己再写一个gen.cpp编译后使用如下system()运行,以下不需要输出到stderr
        system("./test"); //windows环境不需要加./,下同
        system("./std");

        if(system("diff test.out test.ans")) { //windows下可以使用fc代替diff
            fprintf(stderr, "WA\n");
            getchar();
        } else
            fprintf(stderr, "AC\n");

        //注意,由于前面gen()中可能使用freopen()对stdout进行了重定,所以不能直接使用printf();如需使用,请在gen()结束后使用如下命令:
        //windows下: freopen("CON", "r", stdin);
        //Linux下: freopen("/dev/console", "r", stdin);
        //以下是spj的例子
        /*一个实数比较的例子,精确到1e-6.
        ifstream out("test.out"), ans("test.ans");
        double a, b;
        out >> a;
        ans >> b;
        if(fabs(a - b) > 1e-6) {
            fprintf(stderr, "WA read: %lf expected: %lf\n", a, b);
            getchar();
            goto ed;
        }
        fprintf(stderr, "AC\n");
        ed: ;
        */
    }

    return 0;
}

一个linux用户

类似于windows下的.bat批处理文件,linux下也可以自行使用脚本进行对拍。

将以下文件保存为.sh(本文为pai.sh),和gen、test、std保存在同一目录下(假设该目录为~/Desktop/AH-2333/test/)。

while true; do
./gen
./test
./std
if diff test.out test.ans; then
echo AC
else
echo WA
exit 0
fi
done

运行时只需要在~/Desktop/AH-2333/test/目录下启动终端(NOI LINUX貌似把这个功能删了,可能需要打开终端手动cd到指定目录,这时可以使用tab键自动补全目录,注意,linux下大小写敏感),然后输入sh pai.sh即可。

最后退出时的.in/.out/.ans即为拍出错误的文件。

如果需要spj,则不能使用系统自带的diff,可以自己手写一个spj.cpp,编译后,将以上的if diff test.out test.ans;改成if ./spj即可。spj的写法如下:

#include <bits/stdc++.h>

using namespace std;

int main()
{
    ifstream out("test.out"), ans("test.ans");
    double   a, b;
    out >> a;
    ans >> b;
    return fabs(a - b) > 1e-6 ? 1 : 0; //0为真
}