TOJ
- 社團練習用的Online Judge
- 由T13的吳哲宇(pzread)開發
- T19的lys0829於2017年將judge更新
- T24的tobiichi3227與ccccchhhheeenng於2022年將後端Server的軟硬體更新
出題
以下內容均為 Problem Package 的形式,TOJ 已經支援用 UI 新增題目了
一般題目
limit欄位的 default 一定要存在,其餘可以填寫 TOJ 支援的編譯器 (gcc, g++, clang, clang++, python3, rust, java)
記憶體限制的單位是 KB
{
"limit": {
"default": {
"timelimit": 1000,
"memlimit": 65536
},
"python3": {
"timelimit": 2500,
"memlimit": 524288,
}
}
check欄位可以填 "diff", "diff-strict"
Type | 解釋 |
---|---|
diff | 寬鬆比對 |
diff-strict | 嚴格比對 |
- /conf.json
{
"limit": {
"default": {
"timelimit": 1000,
"memlimit": 65536
}
},
"is_makefile": false,
"check": "diff",
"test": [
{
"data": [
1, 2, 3, 4, 5, "hard-1"
],
"weight": 100
}
]
}
data的部份是測資檔案名稱 需將檔案放到 /res/testdata 下面
輸入輸出檔都需要 (.in, .out)
Makefile題目 (編譯互動題)
- /conf.json
{
"limit": {
"default": {
"timelimit": 1000,
"memlimit": 65536
}
},
"is_makefile": true,
"check": "diff",
"test": [
{
"data": [
1, 2, 3, 4, 5
],
"weight": 100
}
]
}
在 res/make 新增 Makefile 與 要編譯的檔案
- /res/make/Makefile
default:
g++ main.cpp stub.cpp -o $(OUT)
stub.cpp 可以自己換成其他要一起編譯的檔案,編譯選項可以自行修改
CMS/Testlib Checker
- /conf.json
{
"limit": {
"default": {
"timelimit": 1000,
"memlimit": 65536
}
},
"check": "cms",
"test": [
{
"data": [
1, 2, 3, 4, 5
],
"weight": 100
}
]
}
- /res/check/check.cpp
會傳入三個參數,分別為測資輸入,測資輸出,答案輸入
#include <fstream>
int main(int argc, char** argv) {
std::ifstream test_in(argv[1]);
std::ifstream test_out(argv[2]);
std::ifstream ans_in(argv[3]);
// C
FILE* test_in_ptr = fopen(argv[1], "r");
FILE* test_out_ptr = fopen(argv[2], "r");
FILE* ans_in_ptr = fopen(argv[3], "r");
fclose(test_in_ptr);
fclose(test_out_ptr);
fclose(ans_in_ptr);
}
- /res/check/check.py
import sys
test_in = open(sys.argv[1])
test_out = open(sys.argv[2])
ans_in = open(sys.argv[3])
test_in.close()
test_out.close()
ans_in.close()
Verdict Message (Checker Message)
對標準錯誤 (STDERR) 輸出 verdict message
C/C++
#include <iostream>
std::cerr << "checker message" << std::endl;
#include <cstdio>
fprintf(stderr, "checker message");
Python
import sys
print("checker message", sys.stderr)
Special Score & Status
對標準輸出 (STDOUT) 輸出 Special Score & Status,輸出標準如下 ScoreType;Score;Status
Score
ScoreType 可以是 NONE, CMS, CF
NONE 代表 Judge 不會理會 Score 的值
CMS 代表 Judge 會將 該題子任務分數乘上 Score (與 CMS 的 GroupMin 相同),且 Score 範圍應該從 0.0 到 1.0,大於 1.0 將設定為 1.0,小於 0.0 將設定為 0.0
CF 代表 Judge 會直接用 Score 覆蓋該子任務分數
Status
Status 可以是 TOJ 所支援的所有 Status (AC, PC, WA, RE, RESIG, TLE, MLE, OLE, CE, CLE, SJE, IE)
如果 Status 為空 或 不在支援的 Status 中將按照 Checker 回傳值決定狀態 (return 0 為 AC,其餘為 WA)
下面列出幾個作為參考
STDOUT String | Score | Status |
---|---|---|
CMS;0.5;PC | 子任務分數 * 0.5 | PC (Partial Correct) |
CF;32.27;AC | 32.27 | AC (Answer Correct) |
NONE;3131;WA | 子任務分數 | WA (Wrong Answer) |
CF;32.27; | 32.27 | 按照 Return 值決定是 AC 或 WA |
;; | 子任務分數 | 按照 Return 值決定是 AC 或 WA |
(沒有任何輸出) | 子任務分數 | 按照 Return 值決定是 AC 或 WA |
- /res/check/build
#!/bin/sh
g++ -o check check.cpp
# python
# cp check.py check
# chmod +x check
IORedir
將conf.json中的 check 從 diff 改成 ioredir,及設定 metadata 如下。 如果 Checker 的 STDOUT 或 STDERR 沒有被佔用且有輸出內容,那 Verdict Message (Checker Message) 將會為該內容 (如果兩個同時都有,STDERR 優先於 STDOUT
- /conf.json
{
"check": "ioredir",
"metadata": {
"redir_test": {
"pipeout": 1,
"testin": 0,
"testout": -1,
"pipein": -1
},
"redir_check": {
"ansin": 2,
"testin": -1,
"pipeout": 0,
"pipein": -1
}
}
}
如果要用 ioredir 實現互動題, metadata 可以這樣寫
從 STDERR 讀入測資,對 STDOUT 輸出測資 從 STDIN 讀入答案
{
"redir_test": {
"pipein": 0,
"testin": -1,
"pipeout": 1,
"testout": -1
},
"redir_check": {
"ansin": -1,
"pipein": 1,
"testin": 2,
"pipeout": 0
}
}
- /res/check/check.cpp
分別從答案及輸出分別讀入long double。
long double Answer, Output;
FILE *ansf = fdopen(2, "r");
scanf("%Lf", &Output);
fscanf(ansf, "%Lf", &Answer);
- /res/check/build
#!/bin/sh
g++ -o check check.cpp
參考 https://hackmd.io/s/BkHdt57I
Polygon to TOJ
請參考 cf2toj
TPS to TOJ
請參考 tps2toj
CMS to TOJ
請參考 cms2toj
小技巧
OI制 (APCS)
可以只上傳範例測資,並把該子任務分數設定為 0
Dependency Tree
假設 subtask2 依賴 subtask1 可以把 subtask1 的所有測資檔名複製到 subtask2 的測資中
偷偷支援目前 TOJ 無法使用的語言
前提:Judge 本身需要支援 可以使用 Makefile 類型的題目 並在編譯時使用其他語言
負分
TOJ其實可以設定子任務分數為負數,但可能會有很多問題 Scoreboard 應該選擇 IOI2013