# [CMS Online Judge] 互動題、Checker :::info 目錄: * [[CMS Online Judge] Docker安裝教學](/WKsC33XYRme4sM-Kkst_XA) * [[CMS Online Judge] 完整安裝教學](/qLOLKTjlQ6ivpN0vg4yb-g) * [[CMS Online Judge] 使用教學](/vzeJxoVGQPipzqd3R0_s9w) * [[CMS Online Judge] 互動題、Checker](/cA70QEPVRROxvTxYujMTcw) * [[CMS Online Judge] 給系統管理者的一些建議](/EOf5VvLOSM6BTjbVfb7vRg) [Github連結](https://github.com/erichung09060/cms) ::: :::success 所有的範例題目都是a+b問題 ``` Input : 3 4 Output : 7 ``` ::: ## Checker 計分方式:checker會輸出一個介於0到1之間的浮點數,0表示沒有拿到分數,1表示完全拿到此題子測資的分數,0.5表示拿到一半子測資的分數,以此類推。 設定步驟: * 把`Output evalution`改成`Outputs are compared by a comparator` * 上傳checker執行檔 :::spoiler checker 編譯指令:`g++ checker.cpp -o checker -static` ```cpp= #include <bits/stdc++.h> using namespace std; int main(int argc, char* argv[]) { ifstream input(argv[1]); ifstream correct_output(argv[2]); ifstream user_output(argv[3]); int userans, ans; user_output >> userans; correct_output >> ans; if (userans == ans) cout << 1.0 << '\n'; else cout << 0.0 << '\n'; } ``` ::: :::spoiler solution ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int a, b; cin >> a >> b; cout << a + b << '\n'; } ``` ::: :::spoiler 示意圖 ![](https://i.imgur.com/UeWurYr.png) ::: ## Loader Code 管理員需要上傳一份Code(Loader Code),judge會把參賽者的Code和Loader Code合併,再去編譯及執行,因此參賽者只需要實作特定的function即可。 設定步驟: * 把`Compilation`改成`Submissions are compiled with a grader` * 上傳Loader code,每一種支持的語言都要上傳一份,否則該語言會無法編譯 * 請注意,Task type不同會需要叫不同的檔名: 1. `Batch Type`:`grader.cpp` 2. `Communication Type`:`stub.cpp` :::spoiler grader.cpp/stub.cpp ```cpp= #include <bits/stdc++.h> using namespace std; int add(int x, int y); int main() { int a,b; cin >> a >> b; cout << add(a, b) << '\n'; } ``` ::: :::spoiler Solution ```cpp= #include <bits/stdc++.h> using namespace std; int add(int a, int b){ return a + b; } ``` ::: :::spoiler 示意圖 Batch Type: ![](https://i.imgur.com/mx9jlOL.png) Communication Type: ![](https://i.imgur.com/Wj8dMxn.png) ::: ## 互動題 讓用戶的程式碼跟judge互動,一來一往,可防止參賽者使用離線算法。 :::warning 要記得設定Time Limit否則會無法編譯。 ::: * 設定`Time Limit`為`1` * 設定`Task Type`為`Communitation` * 設定`Number of Processes`為`1` * 設定`User I/O`為` User processes read from stdin and write to stdout ` * 上傳manager.cpp的執行檔,做為參賽者互動的對象 ### 例題 一樣a+b問題,但參賽者不知道有幾次查詢,計算完並輸出結果後judge才會告訴你下一組查詢。 #### 測資 ``` Input : 2 3 4 34587378934534 32452384572389 Output : 7 67039763506923 ``` :::spoiler manager.cpp 編譯指令:`g++ manager.cpp -o manager -static` manager最後會需要輸出一個0到1之間的數,用法跟checker一樣用來計算分數。 ```cpp= #include <bits/stdc++.h> using namespace std; using ll = long long; int main(int argc, char **argv) { ofstream to_user(argv[2]); ifstream from_user(argv[1]); int n; cin >> n; double score = 0; for (int i = 1; i <= n; i++) { ll a, b, userans; cin >> a >> b; to_user << a << ' ' << b << endl; from_user >> userans; ll ans = a + b; score += (userans == ans) * 1.0 / n; } cout << score << '\n'; to_user.close(); from_user.close(); } ``` ::: :::spoiler solution.cpp ```cpp= #include <bits/stdc++.h> using namespace std; int main(int argc, char **argv) { long long a, b; while(cin >> a >> b){ cout << a + b << endl; } } ``` ::: :::spoiler 示意圖 ![image](https://hackmd.io/_uploads/rkd1ioig0.png) ::: ------------------------ ## 注意事項 :::warning 1. 要上傳的checker及manager為編譯過後的執行檔,請勿直接上傳.cpp檔。 2. 如果編譯出來的執行檔在cms上無法執行,請換一台電腦編譯。 3. `Communication Type`一定要使用`endl`或`flush`來清空緩衝區。 :::