Try   HackMD

[CMS Online Judge] 互動題、Checker

所有的範例題目都是a+b問題

Input : 
3 4

Output : 
7

Checker

計分方式:checker會輸出一個介於0到1之間的浮點數,0表示沒有拿到分數,1表示完全拿到此題子測資的分數,0.5表示拿到一半子測資的分數,以此類推。

設定步驟:

  • Output evalution改成Outputs are compared by a comparator
  • 上傳checker執行檔
checker

編譯指令:g++ checker.cpp -o checker -static

#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'; }
solution
#include <bits/stdc++.h> using namespace std; int main() { int a, b; cin >> a >> b; cout << a + b << '\n'; }
示意圖

Loader Code

管理員需要上傳一份Code(Loader Code),judge會把參賽者的Code和Loader Code合併,再去編譯及執行,因此參賽者只需要實作特定的function即可。

設定步驟:

  • Compilation改成Submissions are compiled with a grader
  • 上傳Loader code,每一種支持的語言都要上傳一份,否則該語言會無法編譯
    • 請注意,Task type不同會需要叫不同的檔名:
      1. Batch Typegrader.cpp
      2. Communication Typestub.cpp
grader.cpp/stub.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'; }
Solution
#include <bits/stdc++.h> using namespace std; int add(int a, int b){ return a + b; }
示意圖

Batch Type:

Communication Type:

互動題

讓用戶的程式碼跟judge互動,一來一往,可防止參賽者使用離線算法。

要記得設定Time Limit否則會無法編譯。

  • 設定Time Limit1
  • 設定Task TypeCommunitation
  • 設定Number of Processes1
  • 設定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
manager.cpp

編譯指令:g++ manager.cpp -o manager -static
manager最後會需要輸出一個0到1之間的數,用法跟checker一樣用來計算分數。

#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(); }
solution.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; } }
示意圖

image


注意事項

  1. 要上傳的checker及manager為編譯過後的執行檔,請勿直接上傳.cpp檔。
  2. 如果編譯出來的執行檔在cms上無法執行,請換一台電腦編譯。
  3. Communication Type一定要使用endlflush來清空緩衝區。