简称 SPJ,这是针对用户输出的特判。比如,根据题面求解出来的答案可能存在多个,这样就无法定义一个准确的输出文件来判断用户是否正确,这时就需要 SPJ。或者允许用户的输出在某一精度范围内是正确的。
SPJ 是一个用C、C++写的可执行程序,其返回值决定着判断结果,成功返回(0)表示AC,其他非零值表示WA。
SPJ 的编译参数为:g++ -fno-asm -std=c++11 -O2 ,即已经开启C++11以及O2优化。
请确保 SPJ 程序的正确运行,也未调用与判题无关的系统函数,当 SPJ 在 OJ 中编译出错或运行出错时,OJ 不会给出反馈。
spj 输出到 stderr(标准错误)
的内容将会被记录到用户错误数据点中。
下面给出两种写 SPJ 的方法,采用其中一种即可。
#include <stdio.h>
当前 OJ 采用了跟 Codeforces 一样的 SPJ 标准,即Testlib库。
下载地址: https://github.com/MikeMirzayanov/testlib
当标准输出和选手输出的差小于0.01,那么可以AC,否则WA。
#include "testlib.h" int main(int argc, char* argv[]) { registerTestlibCmd(argc, argv); double pans = ouf.readDouble(); double jans = ans.readDouble(); if (fabs(pans - jans)<0.01) quitf(_ok, "The answer is correct."); else quitf(_wa, "The answer is wrong: expected = %f, found = %f", jans, pans); }
在程序中,有3个重要的结构体:inf指数据输入文件(本例没有),ouf指选手输出文件,ans指标准答案。
然后,可以从这3表结构体读入数据,不需要用到标准输入输出。如果读到的数据和下面的期望不一致,则spj返回fail结果。
这边继续给出一个多行(不定行数)的spj判断:
#include "testlib.h" int main(int argc, char* argv[]) { registerTestlibCmd(argc, argv); while(!ans.eof()){ double pans = ouf.readDouble(); double jans = ans.readDouble(); ans.readEoln(); if (fabs(pans - jans)>0.01) quitf(_wa, "The answer is wrong: expected = %f, found = %f", jans, pans); } quitf(_ok, "The answer is correct."); return 0; }
以下读入命令可以使用:
初始化checker,必须在最前面调用一次:void registerTestlibCmd(argc, argv)
读入一个char,指针后移一位:char readChar()
和上面一样,但是只能读到一个字母c:char readChar(char c)
同 readChar(' '):char readSpace()
读入一个字符串,但是遇到空格、换行、eof为止:string readToken()
读入一个long long/int64:long long readLong()
同上,但是限定范围(包括L,R):long long readLong(long long L, long long R)
读入一个int:int readInt()
同上,但是限定范围(包括L,R):int readInt(int L, int R)
读入一个实数:double readReal()
同上,但是限定范围(包括L,R):double readReal(double L, double R)
读入一个限定范围精度位数的实数:double readStrictReal(double L, double R, int minPrecision, int maxPrecision)
读入string,到换行或者eof为止:string readString(), string readLine()
读入一个换行符: void readEoln()
读入一个eof:void readEof()
输出:
给出 AC:quitf(\_ok, "The answer is correct. answer is %d", ans);
给出 WA:quitf(\_wa, "The answer is wrong: expected = %f, found = %f", jans, pans);
./spj in.txt out.txt ans.txt # Linux spj.exe in.txt out.txt ans.txt # Windows