TOJ

出自TFcisWiki
跳至導覽 跳至搜尋


https://toj.tfcis.org/oj/

出題

以下內容均為 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

參見