跳转至

通用

本頁面介紹 Testlib checker/interactor/validator 的一些通用狀態/對象/函數、一些用法及注意事項。請在閲讀其他頁面前完整閲讀本頁面的內容。

通用狀態

結果 Testlib 別名 含義
Ok _ok 答案正確。
Wrong Answer _wa 答案錯誤。
Presentation Error _pe 答案格式錯誤。注意包括 Codeforces 在內的許多 OJ 並不區分 PE 和 WA。
Partially Correct _pc(score) 答案部分正確。僅限於有部分分的測試點,其中 score 為一個正整數,從 \(0\)(沒分)到 \(100\)(可能的最大分數)。
Fail _fail validator 中表示輸入不合法,不通過校驗。
checker 中表示程序內部錯誤、標準輸出有誤或選手輸出比標準輸出更優,需要裁判/出題人關注。(也就是題目鍋了)

通常用程序的返回值表明結果,但是也有一些其他方法:創建一個輸出 xml 文件、輸出信息到 stdout 或其他位置……這些都通過下方函數表中的 quitf 函數來完成。

通用對象

對象 含義
inf 輸入文件流
ouf 選手輸出流
ans 參考輸出流

通用函數

非成員函數:

調用 含義
void registerTestlibCmd(int argc, char* argv[]) 註冊程序為 checker
void registerInteraction(int argc, char* argv[]) 註冊程序為 interactor
void registerValidation()/void registerValidation(int argc, char* argv[]) 註冊程序為 validator
void registerGen(int argc, char* argv[], int randomGeneratorVersion) 註冊程序為 generator
randomGeneratorVersion 推薦為 1
void quit(TResult verdict, string message)/void quitf(TResult verdict, string message, ...) 結束程序,返回 verdict,輸出 message
void quitif(bool condition, TResult verdict, string message, ...) 如果 condition 成立,調用 quitf(verdict, message, ...)

流成員函數:

調用 含義
char readChar() 讀入一個字符
char readChar(char c) 讀入一個字符,必須為 c
char readSpace() 等同於 readChar(' ')
string readToken()/string readWord() 讀入一個串,到空白字符(空格、Tab、EOLN 等)停止
string readToken(string regex)/string readWord(string regex) 讀入一個串,必須與 regex 匹配
long long readLong() 讀入一個 64 位整數
long long readLong(long long L, long long R) 讀入一個 64 位整數,必須在 \([L,R]\) 之間
vector<long long> readLongs(int n, long long L, long long R) 讀入 \(N\) 個 64 位整數,必須均在 \([L,R]\) 之間
int readInt()/int readInteger() 讀入一個 32 位整數
int readInt(int L, int R)/int readInteger(L, R) 讀入一個 32 位整數,必須在 \([L,R]\) 之間
vector<int> readInts(int n, int L, int R)/vector<int> readIntegers(int n, int L, int R) 讀入 \(N\) 個 32 位整數,必須均在 \([L,R]\) 之間
double readReal()/double readDouble() 讀入一個雙精度浮點數
double readReal(double L, double R)/double readDouble(double L, double R) 讀入一個雙精度浮點數,必須在 \([L,R]\) 之間
double readStrictReal(double L, double R, int minPrecision, int maxPrecision)/double readStrictDouble(double L, double R, int minPrecision, int maxPrecision) 讀入一個雙精度浮點數,必須在 \([L,R]\) 之間,小數位數必須在 \([minPrecision,maxPrecision]\) 之間,不得使用指數計數法等非正常格式
string readString()/string readLine() 讀入一行(包括換行符),同時將流指針指向下一行的開頭
string readString(string regex)/string readLine(string regex) 讀入一行,必須與 regex 匹配
void readEoln() 讀入 EOLN(在 Linux 環境下讀入 LF,在 Windows 環境下讀入 CR LF
void readEof() 讀入 EOF
void quit(TResult verdict, string message)/void quitf(TResult verdict, string message, ...) 結束程序,若 Streamouf 返回 verdict,否則返回 _fail;輸出 message
void quitif(bool condition, TResult verdict, string message, ...) 如果 condition 成立,調用 quitf(verdict, message, ...)

未完待續……

極簡正則表達式

上面的輸入函數中的一部分允許使用「極簡正則表達式」特性,如下所示:

  • 字符集。如 [a-z] 表示所有小寫英文字母,[^a-z] 表示除小寫英文字母外任何字符。
  • 範圍。如 [a-z]{1,5} 表示一個長度在 \([1,5]\) 範圍內且只包含小寫英文字母的串。
  • 「或」標識符。如 mike|john 表示 mikejohn 其一。
  • 「可選」標識符。如 -?[1-9][0-9]{0,3} 表示 \([-9999,9999]\) 範圍內的非零整數(注意那個可選的負號)。
  • 「重複」標識符。如 [0-9]* 表示零個或更多數字,[0-9]+ 表示一個或更多數字。
  • 注意這裏的正則表達式是「貪婪」的(「重複」會盡可能匹配)。如 [0-9]?1 將不會匹配 1(因為 [0-9]?1 匹配上,導致模板串剩餘的那個 1 無法匹配)。

首先 include testlib.h

請確保 testlib.h 是你 include 的 第一個 頭文件,Testlib 會重寫/禁用(通過名字衝突的方式)一些與隨機有關的函數(如 random()),保證隨機結果與環境無關,這對於 generator 非常重要,generator 頁面 會詳細説明這一點。

使用項別名

推薦給 readInt/readInteger/readLong/readDouble/readWord/readToken/readString/readLine 等的有限制調用最後多傳入一個 string 參數,即當前讀入的項的別名,使報錯易讀。例如使用 inf.readInt(1, 100, "n") 而非 inf.readInt(1, 100),報錯信息將為 FAIL Integer parameter [name=n] equals to 0, violates the range [1, 100]

使用 ensuref/ensure()

這兩個函數用於檢查條件是否成立(類似於 assert())。例如檢查 \(x_i \neq y_i\),我們可以使用

1
ensuref(x[i] != y[i], "Graph can't contain loops");

還可以使用 C 風格佔位符如

1
2
3
ensuref(s.length() % 2 == 0,
        "String 's' should have even length, but s.length()=%d",
        int(s.length()));

它有一個簡化版 ensure(),我們可以直接使用 ensure(x> y) 而不添加説明內容(也不支持添加説明內容),如果條件不滿足報錯將為 FAIL Condition failed: "x > y"。很多情況下不加額外的説明的這種報錯很不友好,所以我們通常使用 ensuref() 並加以説明內容,而非使用 ensure()

Warning

注意全局與成員 ensuref/ensure() 的區別

全局函數 ::ensuref/ensure() 多用於 generator 和 validator 中,如果檢查失敗將統一返回 _fail

成員函數 InStream::ensuref/ensure() 一般用於判斷選手和參考程序的輸出是否合法。當 InStreamouf 時,返回 _wa;為 inf(一般不在 checker 中檢查輸入數據,這應當在 validator 中完成)或 ans 時,返回 _fail。詳見 Checker - 編寫 readAns 函數

本文主要翻譯並綜合自 Testlib - Codeforces 系列。testlib.h 的 GitHub 存儲庫為 MikeMirzayanov/testlib