「TPS」:修訂間差異
無編輯摘要 |
(→操作方式) |
||
行 53: | 行 53: | ||
== 操作方式 == |
== 操作方式 == |
||
本頁面主要使用 |
本頁面主要使用 TNFSH-Programming-Contest/cms-environment-testing-problem<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem</ref> 的 pB<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB</ref> 作為範本。 |
||
[[File:Icon tools.svg|20px]] 以下有此標誌的說明需要 CMS 系統管理員操作,出題者可忽略此說明。 |
[[File:Icon tools.svg|20px]] 以下有此標誌的說明需要 CMS 系統管理員操作,出題者可忽略此說明。 |
||
{{reflist-talk}} |
|||
=== 建立GitHub Repo === |
=== 建立GitHub Repo === |
||
# 進入 |
# 進入 tps-starter。<ref>https://github.com/TNFSH-Programming-Contest/tps-starter</ref> |
||
# 點擊 Use this template。<ref>直接連結:https://github.com/TNFSH-Programming-Contest/tps-starter/generate</ref> |
|||
# 填寫Repo資訊 |
# 填寫Repo資訊 |
||
#* Repository name 填入競賽英文名,例如「cms-environment-testing-problem」。 |
#* Repository name 填入競賽英文名,例如「cms-environment-testing-problem」。 |
||
行 64: | 行 67: | ||
#* [[File:OOjs UI icon alert-destructive.svg|20px]] '''注意:'''可見度必須選擇 '''Private'''。 |
#* [[File:OOjs UI icon alert-destructive.svg|20px]] '''注意:'''可見度必須選擇 '''Private'''。 |
||
#* 點擊 Create repository from template。 |
#* 點擊 Create repository from template。 |
||
{{reflist-talk}} |
|||
=== 建立新題目 === |
=== 建立新題目 === |
||
行 81: | 行 86: | ||
需寫入於:(範例為「CMS環境測試題目通用版 v1.1」) |
需寫入於:(範例為「CMS環境測試題目通用版 v1.1」) |
||
# |
# cover.tex。<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/blob/main/cover.tex</ref> |
||
# 各題目 |
# 各題目 problem.json<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/blob/main/pB/problem.json</ref> 的 contest_name 欄位。 |
||
# [[File:Icon tools.svg|20px]] CMS 管理系統的 Description 欄位。 |
# [[File:Icon tools.svg|20px]] CMS 管理系統的 Description 欄位。 |
||
{{reflist-talk}} |
|||
=== 題目名稱 === |
=== 題目名稱 === |
||
行 91: | 行 98: | ||
# 該題目各頁右上角。 |
# 該題目各頁右上角。 |
||
需寫入於 |
需寫入於 problem.json<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/blob/main/pB/problem.json</ref> 的 title 欄位,範例為「Piñata」。 |
||
{{reflist-talk}} |
|||
=== 題目英文名稱 === |
=== 題目英文名稱 === |
||
行 101: | 行 110: | ||
# 可能作為 GitHub repo 內的題目資料夾名稱。 |
# 可能作為 GitHub repo 內的題目資料夾名稱。 |
||
需寫入於 |
需寫入於 problem.json<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/blob/main/pB/problem.json</ref> 的 name 欄位,範例為「Pinata」。 |
||
{{reflist-talk}} |
|||
=== 題目編號 === |
=== 題目編號 === |
||
行 110: | 行 121: | ||
=== 記憶體限制 === |
=== 記憶體限制 === |
||
需寫入於 |
需寫入於 problem.json<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/blob/main/pB/problem.json</ref> 的 memory_limit 欄位,單位為MB,範例為「512」MB。 |
||
{{reflist-talk}} |
|||
=== 時間限制 === |
=== 時間限制 === |
||
需寫入於 |
需寫入於 problem.json<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/blob/main/pB/problem.json</ref> 的 time_limit 欄位,單位為秒,範例為「1.0」秒。 |
||
{{reflist-talk}} |
|||
=== 標程 === |
=== 標程 === |
||
⚫ | AC code(官方解法、標程等)需放置在 solution<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB/solution</ref> 資料夾內,檔名無限制。同時將該檔名寫入 solutions.json<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/blob/main/pB/solutions.json</ref> ,格式請參照範本,verdict 必須標記為 model_solution,範例檔名為「ac.cpp」<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB/solution/ac.cpp</ref>。 |
||
{{sidebar |
|||
|titlestyle=font-size: 110%; |
|||
|title=參考資料 |
|||
|contentstyle=text-align: left; |
|||
|content1= |
|||
* [https://github.com/ioi-2017/tps/tree/master/docs#solutionsjson tps solutions.json 說明] |
|||
* [https://github.com/TNFSH-Programming-Contest/tps-task-templates/blob/93cff7e64a43f57450b26568194432e7b662be38/default/scripts/internal/invoke.py#L18 tps script is_verdict_expected] |
|||
⚫ | |||
* 範例 [https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB/solution/ac.cpp ac.cpp] |
|||
* 範例 [https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/blob/main/pB/solutions.json solutions.json] |
|||
}} |
|||
⚫ | |||
其他 AC code 亦按照前述方式操作,verdict 必須標記為 correct。 |
其他 AC code 亦按照前述方式操作,verdict 必須標記為 correct。 |
||
其他類型的錯誤解法亦按照前述方式操作,verdict 標記方式請參考 |
其他類型的錯誤解法亦按照前述方式操作,verdict 標記方式請參考官方說明<ref>https://github.com/ioi-2017/tps/tree/master/docs#solutionsjson</ref>及 tps script<ref>https://github.com/TNFSH-Programming-Contest/tps-task-templates/blob/93cff7e64a43f57450b26568194432e7b662be38/default/scripts/internal/invoke.py#L18</ref>。 |
||
{{reflist-talk}} |
|||
=== 產測資 === |
=== 產測資 === |
||
行 141: | 行 147: | ||
==== 產測資程式 ==== |
==== 產測資程式 ==== |
||
{{sidebar |
|||
|titlestyle=font-size: 110%; |
|||
|title=參考資料 |
|||
|contentstyle=text-align: left; |
|||
|content1= |
|||
* [https://en.cppreference.com/w/cpp/language/main_function Main function - cppreference.com] |
|||
* [https://stackoverflow.com/questions/3024197/what-does-int-argc-char-argv-mean c++ - What does int argc, char *argv[] mean? - Stack Overflow] |
|||
* [https://codeforces.com/blog/entry/18291 Generators with testlib.h] |
|||
}} |
|||
{{Memo|'''重要:'''產測資程式必須 |
{{Memo|'''重要:'''產測資程式必須 |
||
# 使用命令列參數讀入測資組及測資點 |
# 使用命令列參數讀入測資組及測資點<ref>[https://en.cppreference.com/w/cpp/language/main_function Main function - cppreference.com]</ref><ref>[https://stackoverflow.com/questions/3024197/what-does-int-argc-char-argv-mean c++ - What does int argc, char *argv[] mean? - Stack Overflow]</ref>。 |
||
# 使用[[zhwiki:stdout|標準輸出(stdout)]],不可直接寫入檔案。 |
# 使用[[zhwiki:stdout|標準輸出(stdout)]],不可直接寫入檔案。 |
||
# 執行一次僅輸出一筆測資。 |
# 執行一次僅輸出一筆測資。 |
||
# 使用 [https://codeforces.com/ |
# 使用 testlib.h<ref>[https://codeforces.com/blog/entry/18291 Generators with testlib.h]</ref> 等設定亂數種子的方式,使得每次產生的測資都是相同的。 |
||
|inline:notice}} |
|inline:notice}} |
||
產測資程式應放置在 |
產測資程式應放置在 gen 資料夾<ref>https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB/gen</ref>內,檔名無限制。 |
||
⚫ | |||
使用 <syntaxhighlight lang="c++" inline>#include "testlib.h"</syntaxhighlight> 引入 testlib 函式庫。 |
|||
main 函數務必寫成 <syntaxhighlight lang="c++" inline>int main(int argc, char* argv[])</syntaxhighlight> 來接收命令列參數。 |
|||
在 main 函數的第一行使用 <syntaxhighlight lang="c++" inline>registerGen(argc, argv, 1);</syntaxhighlight> 將命令列參數作為亂數種子。 |
|||
命令列參數會保存在 <syntaxhighlight lang="c++" inline>argv</syntaxhighlight> |
|||
<syntaxhighlight lang="c++" inline>string task = argv[1];</syntaxhighlight> |
|||
假設以下程式碼編譯成檔名為 gen 的執行檔(在 Windows 上的 gen.exe),那麼可以在命令列使用: |
假設以下程式碼編譯成檔名為 gen 的執行檔(在 Windows 上的 gen.exe),那麼可以在命令列使用: |
||
行 164: | 行 173: | ||
* <code>gen neg 10</code> 隨機產生一個 -10 ~ -1 之間的數字 |
* <code>gen neg 10</code> 隨機產生一個 -10 ~ -1 之間的數字 |
||
* <code>gen neg 20</code> 隨機產生一個 -20 ~ -1 之間的數字 |
* <code>gen neg 20</code> 隨機產生一個 -20 ~ -1 之間的數字 |
||
<syntaxhighlight lang="c++" line> |
|||
#include <bits/stdc++.h> |
|||
#include "testlib.h" |
|||
using namespace std; |
|||
int main(int argc, char* argv[]) { |
|||
registerGen(argc, argv, 1); |
|||
string task = argv[1]; |
|||
int range = atoi(argv[2]); |
|||
if (task == "pos") { |
|||
cout << rnd.next(1, range) << endl; |
|||
} else { |
|||
cout << rnd.next(-range, -1) << endl; |
|||
} |
|||
return 0; |
|||
}</syntaxhighlight> |
|||
;程式碼說明 |
;程式碼說明 |
||
* Line 5:將整個命名列參數註冊為亂數種子,照抄即可。 |
* Line 5:將整個命名列參數註冊為亂數種子,照抄即可。 |
||
行 186: | 行 181: | ||
* Line 9:隨機產生 1 ~ range 之間的數字。 |
* Line 9:隨機產生 1 ~ range 之間的數字。 |
||
* Line 11:隨機產生 -range ~ -1 之間的數字。 |
* Line 11:隨機產生 -range ~ -1 之間的數字。 |
||
{{reflist-talk}} |
|||
==== 產測資指令 ==== |
==== 產測資指令 ==== |
於 2022年8月16日 (二) 16:10 的修訂
TPS(Task Preparation System)是一套可以方便產生題目測試資料以及題本的工具,關於 TPS 可以參考以下的 GitHub Repo:
- TPS Example:https://github.com/TNFSH-Programming-Contest/TPS-example
- IOI 2017 TPS:https://github.com/ioi-2017/tps
資料夾結構
根目錄
資料夾或檔案 | 說明 |
---|---|
.github/workflows/ | Github 自動化流程設定檔 |
pA/ | 題目A |
pB/ | 題目A |
Makefile | 匯入 CMS 的指令 |
README.md | |
cover.tex | 題本封面 |
template.tex | 題本內文模板,不需修改 |
題目目錄
資料夾或檔案 | 說明 |
---|---|
attachments/ | CMS 題目敘述頁的附件,通常僅會在第一題的附件放置合併題本。 |
gen/ | 產測資程式 |
scripts/ | TPS scripts,不需修改 |
solution/ | 標程 |
statement/ | 題目敘述 |
tests/ | 測資檔 |
validator/ | 驗測資程式 |
problem.json | 競賽名稱、題目名稱、題目英文名稱、題目編號、記憶體限制、時間限制 |
solutions-check.txt | 所有標程的執行結果報告 |
solutions.json | 標程、產測資指定的標程 |
subtasks.json | 子任務、使用的驗測資程式 |
操作方式
本頁面主要使用 TNFSH-Programming-Contest/cms-environment-testing-problem[1] 的 pB[2] 作為範本。
以下有此標誌的說明需要 CMS 系統管理員操作,出題者可忽略此說明。
參考資料
建立GitHub Repo
參考資料
建立新題目
- 進入由 tps-starter 建立的 GitHub repo。
- 點擊 Actions。
- 在 Workflows 段落,點擊 New problem。
- 點擊 Run workflow,在 Folder name to create 輸入要建立的資料夾名稱。
- 資料夾名稱僅供命題人員識別用,不會顯示給參賽者。請命名為「pA、pB...」。
- 點擊藍色 Run workflow 按鈕。
- 等待題目目錄建立完成,約 1 分鐘。
競賽名稱
競賽名稱使用於:
- CMS 參賽介面左上角。
- 題本封面第一行。
- 題本內文各頁的左上角。
需寫入於:(範例為「CMS環境測試題目通用版 v1.1」)
參考資料
題目名稱
題目名稱使用於:
- CMS 題目敘述頁面。
- 題目標題(第一頁第一行)。
- 該題目各頁右上角。
需寫入於 problem.json[1] 的 title 欄位,範例為「Piñata」。
參考資料
題目英文名稱
題目英文名稱應足以讓所有命題人員識別個別題目即可,通常取自於中文題目名稱,並盡量僅使用一個英文詞,首字大寫,若需要兩個英文詞以上,則使用PascalCase。使用於:
- CMS 參賽介面題目列表。
- CMS 題目敘述。
- CMS 系統內部用來識別題目的 Primary key。
- 由於同一 CMS 系統上的名稱無法重複,若與其他競賽題目衝突[1],建議加上競賽名稱的英文縮寫作為前綴(例如「2022P-」)。
- 可能作為 GitHub repo 內的題目資料夾名稱。
需寫入於 problem.json[2] 的 name 欄位,範例為「Pinata」。
參考資料
題目編號
題目編號為 A, B, C... 的流水號,在決定題目順序後才會確定,使用於:(範例為「B」)
- 題目標題(第一頁第一行)。
- 該題目各頁右上角。
- 該題目各頁頁碼處。
記憶體限制
需寫入於 problem.json[1] 的 memory_limit 欄位,單位為MB,範例為「512」MB。
參考資料
時間限制
需寫入於 problem.json[1] 的 time_limit 欄位,單位為秒,範例為「1.0」秒。
參考資料
標程
AC code(官方解法、標程等)需放置在 solution[1] 資料夾內,檔名無限制。同時將該檔名寫入 solutions.json[2] ,格式請參照範本,verdict 必須標記為 model_solution,範例檔名為「ac.cpp」[3]。
其他 AC code 亦按照前述方式操作,verdict 必須標記為 correct。
其他類型的錯誤解法亦按照前述方式操作,verdict 標記方式請參考官方說明[4]及 tps script[5]。
參考資料
- ↑ https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB/solution
- ↑ https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/blob/main/pB/solutions.json
- ↑ https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB/solution/ac.cpp
- ↑ https://github.com/ioi-2017/tps/tree/master/docs#solutionsjson
- ↑ https://github.com/TNFSH-Programming-Contest/tps-task-templates/blob/93cff7e64a43f57450b26568194432e7b662be38/default/scripts/internal/invoke.py#L18
產測資
TPS 產測資方式與 Codeforces polygon 相同。測資可以使用手產測資檔案,亦可由程式亂數產生,亦可混合兩者。
手產測資檔
手產測資檔應放置在 gen/manual 資料夾內,檔名無限制,但建議副檔名為 .in。
產測資程式
- 使用命令列參數讀入測資組及測資點[1][2]。
- 使用標準輸出(stdout),不可直接寫入檔案。
- 執行一次僅輸出一筆測資。
- 使用 testlib.h[3] 等設定亂數種子的方式,使得每次產生的測資都是相同的。
產測資程式應放置在 gen 資料夾[4]內,檔名無限制。
以下說明請配合範例檔案 gen/gen.cpp[5]。
使用 #include "testlib.h"
引入 testlib 函式庫。
main 函數務必寫成 int main(int argc, char* argv[])
來接收命令列參數。
在 main 函數的第一行使用 registerGen(argc, argv, 1);
將命令列參數作為亂數種子。
命令列參數會保存在 argv
string task = argv[1];
假設以下程式碼編譯成檔名為 gen 的執行檔(在 Windows 上的 gen.exe),那麼可以在命令列使用:
gen pos 10
隨機產生一個 1 ~ 10 之間的數字gen pos 20
隨機產生一個 1 ~ 20 之間的數字gen neg 10
隨機產生一個 -10 ~ -1 之間的數字gen neg 20
隨機產生一個 -20 ~ -1 之間的數字
- 程式碼說明
- Line 5:將整個命名列參數註冊為亂數種子,照抄即可。
- Line 6:可以將 argv 儲存在 string 變數,之後可用來判斷。
- Line 7:如果有需要轉成整數或其他型態,可以使用 atoi 等函數轉型。
- Line 8:判斷測資點。
- Line 9:隨機產生 1 ~ range 之間的數字。
- Line 11:隨機產生 -range ~ -1 之間的數字。
參考資料
- ↑ Main function - cppreference.com
- ↑ c++ - What does int argc, char *argv[] mean? - Stack Overflow
- ↑ Generators with testlib.h
- ↑ https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB/gen
- ↑ https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/blob/main/pB/gen/gen.cpp
產測資指令
產測資指令應放置在 gen/data。
每一個測資點以 @subtask 接測資點代號為開頭,這個測資點代號亦會使用在#子任務配分。
接下來每個測資點可以有多筆測資,每筆測資可以使用手產測資檔,也可使用產測資程式。
- 使用手產測資檔則為 manual 接續放在 gen/manual 資料夾內的測資檔名。
- 使用產測資程式則為呼叫在命令列中的指令。
@subtask samples
manual example-1.in
@subtask positive
gen pos 20 test1-1
gen pos 20 test1-2
@subtask negative
gen neg 30 test2-1
gen neg 30 test2-2
如果呼叫產測程式,但在指令中輸入了兩行一模一樣的內容,那麼這兩個測資就會相同(在設定亂數種子的情況下),因此通常會在後面放上隨機文字作為亂數種子的一部分,亦可透過更換亂數種子來重新產生測資,隨機文字可使用 Random String Generator 產生。
- 透過命令列參數直接控制測資範圍,就不需要在產測資程式碼內判斷測資點。
- 發現不良的測資時,透過修改命令列參數的隨機文字來得到一筆新的隨機測資。
- 若需要 edge case,使用手產測資檔。
驗測資程式
如果你寫了一個程式解題的問題,並準備好了測試資料,那麼你將可能會遇到一個恐怖的經驗:測試資料是無效的!(即測試資料並未符合題目所規定的限制),例如超過了範圍上限、你的圖實際上沒有連通、或是你的圖不是一棵樹……你很可能會有這種經驗,就算是有經驗的出題者也可能有時會出錯(知名案例像是 ACM ICPC World final 2007)。
——翻譯自 Codeforces 上對於 Validator 的引言。
驗測資程式應該放置在 validator 資料夾內,檔名無限制,並將檔名寫入 subtasks.json 的 global_validators 或 subtasks 的 validators。
以下程式碼範例配合#產測資程式的範例。
#include "testlib.h"
using namespace std;
const int MAXN = 1000;
int main() {
registerValidation();
inf.readInt(-MAXN, MAXN, "n");
inf.readEoln();
inf.readEof();
return 0;
}
- 程式碼說明
- Line 5:初始化 testlib,照抄即可。
- Line 6:預期讀入一個範圍在 -1000 ~ 1000 之間的整數。
- Line 7:預期讀入一個換行。
- Line 8:預期已經讀到檔案結尾。
除了檢查範圍以外,readInt 等函數會回傳其數值,可以保存到變數上作進一步檢查,例如檢查陣列數值皆相異,檢查是否是圖、樹或其他資料結構。
更多的說明請參見 Codeforces。
子任務
子任務設定於 subtasks.json,包含各子任務的配分、文字描述、#驗測資程式。
{
"global_validators": [
"validator.cpp"
],
"subtasks": {
"samples": {
"index": 0,
"score": 0,
"text": "範例輸入輸出",
"validators": []
}
}
}
- 設定說明
- global_validators:在所有測資使用的驗測資程式。
- Line 5:子任務代號,參見#產測資指令。
- index:流水號,出現在題本內的順序,從 0 開始;samples 必為 0。
- score:子任務分數;samples 必為 0。
- text:子任務描述,使用在題目描述內。
- validators:僅在該子任務使用的驗測資程式。
題目敘述
題本檔案放置於 statement/index.md。使用 Markdown 及 XeTeX 語法。
結構由上到下依序為:
題目圖片
題目圖片不是必須的,但通常會有。題目圖片通常與題目本文中使用的故事相關,例如使用動畫設定作為背景故事則會使用該動畫的截圖。
語法為:
\begin{figure}[h]
\centering
\includegraphics[width=12cm]{FILENAME.jpg}
\caption{圖片說明,出自動畫《動畫名稱》}
\end{figure}
題目本文
參見題目敘述故事。
輸入及輸出說明
輸入輸出說明必須明確說明參賽者要遵守的格式。
應該以一行敘述測資中的一行所代表的資料,例如:
- 第一行有 1 個整數,代表接下來的測資數量。
- 第一行有 2 個整數,代表初始座標。
如果需要在其他地方(輸入說明的其他行、輸入限制、題目本文等)提到該變數,應賦予變數代號,例如:
- 第一行有 2 個整數 , 代表點的數量, 代表邊的數量。
- 第一行有 1 個整數 ,代表有 個人。...(換行)...接下來有 行,每一行有 1 個整數代表該人的分數。
輸入限制
輸入限制用來告知參賽者測資的數值範圍限制,
原始碼 | 顯示結果 |
---|---|
- $1 \leq N \leq 100$
- $1 \leq M \leq N$
- $Y - X$ 必定為 2 個倍數
- 若 $A = 1$,則 $B > 0$
|
|
子任務說明
參見子任務的操作,即會自動顯示於題本中。
範例輸入及輸出
範例輸入輸出必須與產測資中設定的範例測資相同。
如果有多筆範例測資,標題應改命名為「範例輸入1、範例輸出1、範例輸入2、範例輸出2」等。
如果有需要說明測資,可加上「範例說明」章節,詳細說明範例測資中的意義,亦可附圖說明。
提示
如有需要,可以提供一些額外提示。如果內容為解題必須的,不應撰寫於提示,應寫於本文中。
亦可撰寫與解題毫無幫助,但與題目故事相關的小知識。