「TPS」:修訂間差異
無編輯摘要 |
(→產測資程式) |
||
行 71: | 行 71: | ||
其他類型的錯誤解法亦按照前述方式操作,verdict 標記方式請參考[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 script]。 |
其他類型的錯誤解法亦按照前述方式操作,verdict 標記方式請參考[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 script]。 |
||
=== 產測資 |
=== 產測資 === |
||
TPS 產測資方式與 Codeforces polygon 相同。測資可以使用手產測資檔案,亦可由程式亂數產生,亦可混合兩者。 |
|||
==== 手產測資檔 ==== |
|||
{{Memo|'''最佳實踐:'''僅在範例測資和 [[:zhwiki:en:Edge case|edge case]] 使用手產測資檔,其他使用產測程式。|}} |
|||
手產測資檔應放置在 [https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB/gen/manual gen/manual] 資料夾內,檔名無限制,但建議副檔名為 .in。 |
|||
==== 產測資程式 ==== |
|||
{{Memo|'''重要:'''產測資程式必須 |
|||
# 使用命令列參數讀入測資組及測資點,參見 [https://en.cppreference.com/w/cpp/language/main_function cppreference]、[https://stackoverflow.com/questions/3024197/what-does-int-argc-char-argv-mean stackoverflow]。 |
|||
# 使用[[zhwiki:stdout|標準輸出(stdout)]],不可直接寫入檔案。 |
|||
# 執行一次僅輸出一筆測資。 |
|||
# 使用 [https://codeforces.com/testlib testlib.h] 等設定亂數種子的方式,使得每次產生的測資都是相同的。 |
|||
|notice}} |
|||
產測資程式應放置在 [https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB/gen gen] 資料夾內,檔名無限制。 |
|||
假設以下程式碼編譯成檔名為 gen 的執行檔(在 Windows 上的 gen.exe),那麼可以在命令列使用: |
|||
* <code>gen pos 10</code> 隨機產生一個 1 ~ 10 之間的數字 |
|||
* <code>gen pos 20</code> 隨機產生一個 1 ~ 20 之間的數字 |
|||
* <code>gen neg 10</code> 隨機產生一個 -10 ~ -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 6:可以將 argv 儲存在 string 變數,之後可用來判斷。 |
|||
* Line 7:如果有需要轉成整數或其他型態,可以使用 atoi 等函數轉型。 |
|||
* Line 8:判斷測資點。 |
|||
* Line 9:隨機產生 1 ~ range 之間的數字。 |
|||
* Line 11:隨機產生 -range ~ -1 之間的數字。 |
|||
==== 產測資指令 ==== |
|||
產測資指令應放置在 [https://github.com/TNFSH-Programming-Contest/cms-environment-testing-problem/tree/main/pB/gen/data gen/data]。 |
|||
每一個測資點以 @subtask 接測資點代號為開頭,這個測資點代號亦會使用在[[#子任務配分]]。 |
|||
接下來每個測資點可以有多筆測資,每筆測資可以使用手產測資檔,也可使用產測資程式。 |
|||
* 使用手產測資檔則為 manual 接續放在 gen/manual 資料夾內的測資檔名。 |
|||
* 使用產測資程式則為呼叫在命令列中的指令。 |
|||
<syntaxhighlight lang="text" line> |
|||
@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 |
|||
</syntaxhighlight> |
|||
如果呼叫產測程式,但在指令中輸入了兩行一模一樣的內容,那麼這兩個測資就會相同(在設定亂數種子的情況下),因此通常會在後面放上隨機文字作為亂數種子的一部分,亦可透過更換亂數種子來重新產生測資,隨機文字可使用 [https://www.random.org/strings/ Random String Generator] 產生。 |
|||
{{Memo|'''小技巧:''' |
|||
# 透過命令列參數直接控制測資範圍,就不需要在產測資程式碼內判斷測資點。 |
|||
# 發現不良的測資時,透過修改命令列參數的隨機文字來得到一筆新的隨機測資。 |
|||
# 若需要 edge case,使用手產測資檔。 |
|||
|}} |
|||
=== 驗測資程式 === |
=== 驗測資程式 === |
於 2022年8月15日 (一) 21:13 的修訂
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
使用方式
以下有此標誌的說明需要 CMS 系統管理員操作,出題者可忽略此說明。
建立Github Repo
- 進入tps-starter。
- 填寫Repo資訊
建立新題目
- 進入由 tps-starter 建立的 Github repo。
- 點擊 Actions。
- 在 Workflows 段落,點擊 New problem。
- 點擊 Run workflow,在 Folder name to create 輸入要建立的資料夾名稱。
- 資料夾名稱僅供命題人員識別用,不會顯示給參賽者。如果已排定題目順序,可用「pA、pB...」命名,亦可用題目的英文簡稱。
- 點擊藍色 Run workflow 按鈕。
- 等待約 1 分鐘。
競賽名稱
競賽名稱使用於:
- CMS 參賽介面左上角。
- 題本封面第一行。
- 題本內文各頁的左上角。
需寫入於:
- cover.tex。
- 各題目 problem.json 的 contest_name 欄位。
- CMS 管理系統的 Description 欄位。
題目名稱
題目名稱使用於:
- CMS 題目敘述頁面。
- 題目標題(第一頁第一行)。
- 該題目各頁右上角。
需寫入於 problem.json 的 title 欄位。
題目英文名稱
題目英文名稱應足以讓所有命題人員識別個別題目即可,通常取自於中文題目名稱,並盡量僅使用一個英文詞,首字大寫,若需要兩個英文詞以上,則使用PascalCase。使用於:
- CMS 參賽介面題目列表。
- CMS 題目敘述。
- CMS 系統內部用來識別題目的 Primary key。
- 由於同一 CMS 系統上的名稱無法重複,若與其他競賽題目衝突[1],建議加上競賽名稱的英文縮寫作為前綴(例如「2022P-」)。
- 可能作為 Github repo 內的題目資料夾名稱。
需寫入於 problem.json 的 name 欄位。
題目編號
題目編號為 A, B, C... 的流水號,在決定題目順序後才會確定,使用於:
- 題目標題(第一頁第一行)。
- 該題目各頁右上角。
- 該題目各頁頁碼處。
記憶體限制
需寫入於 problem.json 的 memory_limit 欄位,單位為MB。
時間限制
需寫入於 problem.json 的 time_limit 欄位,單位為秒。
標程
AC code(官方解法、標程等)需放置在 solution 資料夾內,檔名無限制。同時將該檔名寫入 solutions.json ,格式請參照範本,verdict 必須標記為 model_solution。
其他 AC code 亦按照前述方式操作,verdict 必須標記為 correct。
其他類型的錯誤解法亦按照前述方式操作,verdict 標記方式請參考官方說明及 tps script。
產測資
TPS 產測資方式與 Codeforces polygon 相同。測資可以使用手產測資檔案,亦可由程式亂數產生,亦可混合兩者。
手產測資檔
手產測資檔應放置在 gen/manual 資料夾內,檔名無限制,但建議副檔名為 .in。
產測資程式
- 使用命令列參數讀入測資組及測資點,參見 cppreference、stackoverflow。
- 使用標準輸出(stdout),不可直接寫入檔案。
- 執行一次僅輸出一筆測資。
- 使用 testlib.h 等設定亂數種子的方式,使得每次產生的測資都是相同的。
產測資程式應放置在 gen 資料夾內,檔名無限制。
假設以下程式碼編譯成檔名為 gen 的執行檔(在 Windows 上的 gen.exe),那麼可以在命令列使用:
gen pos 10
隨機產生一個 1 ~ 10 之間的數字gen pos 20
隨機產生一個 1 ~ 20 之間的數字gen neg 10
隨機產生一個 -10 ~ -1 之間的數字gen neg 20
隨機產生一個 -20 ~ -1 之間的數字
#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;
}
- 程式碼說明
- Line 5:將整個命名列參數註冊為亂數種子,照抄即可。
- Line 6:可以將 argv 儲存在 string 變數,之後可用來判斷。
- Line 7:如果有需要轉成整數或其他型態,可以使用 atoi 等函數轉型。
- Line 8:判斷測資點。
- Line 9:隨機產生 1 ~ range 之間的數字。
- Line 11:隨機產生 -range ~ -1 之間的數字。
產測資指令
產測資指令應放置在 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,使用手產測資檔。