No.5000 特殊ジャッジテスト(テスト用)
タグ : / 解いたユーザー数 200
作問者 :
作問者向けNote 2026/05/10 更新
スペシャルジャッジ・リアクティブの検証コードの実行の仕様です。 実行コマンド (問題の入力ファイルパス) (問題の出力ファイルパス) (提出されたソースコードのパス) (スコアファイルのパス)
(標準入力に提出コードでの標準出力が渡される)
実行コマンドの例です。
./a.out test_in/1.txt ans/1.txt main.ws score/1.txt < out/1.txt
検証コードで気をつけないといけないのは、提出コードでの標準出力には言語によりCR(改行コード: キャリッジリターン)が含まれる可能性があるので、可能な限りケアするようにしてください。
特にC++のstd::getline はジャッジ環境ではCRを解釈してくれません。
参考 std::getlineについての覚書
同じように他のCRを考慮しないものがあればご提案ください。
検証コードがランタイムエラー(Exit Codeが
0以外。例えばassertなどで終了)になるとWAになります。検証コードがTLEすると
J_TLEになりますが、なるべくならないようにしてください。リアクティブジャッジの場合、検証コードがランタイムエラーかつ、ユーザーコードがTLEの時は
WAになります。Exit Codeを
100としてプログラムを終了させるとQLEになります。(2019/11/14 追加 暫定案)その他
REやTLEなどの判定は通常のチェッカーが使われます。スペシャルジャッジ・リアクティブどちらもテスト出力ファイルをおいてください。空ファイル(0バイトのファイル)で十分ですが、 解の1例をおいておくと良いかもしれません。
リアクティブ問題の(検証コードに対する)入力は、問題の「テスト入力ファイル」においてください。
検証コードでの標準エラー出力は自由に出してもらっても構いません。
リアクティブ問題に関して
リアクティブ問題では、ジャッジコードと解答プロセスが標準入出力を介して双方向にライブ通信します。FD0/FD1 の意味付けはスペシャルジャッジと同様(FD0 に解答の stdout、FD1 から解答の stdin へ)ですが、ファイル経由のバッチではなく実時間のパイプで繋がる点が異なります。
FD0(stdin): 解答プロセスの stdout が接続される(解答が出力した内容をジャッジが読み取る)FD1(stdout): 解答プロセスの stdin に接続される(ジャッジから解答プロセスに入力を送る)FD2(stderr): 自由に使用可能(ログ出力など)
テスト入力ファイルの内容は標準入力には流れません(スペシャルジャッジでも同様で、FD0 は解答プロセスの出力で占有されます)。必要な場合はコマンドライン引数で渡される入力ファイルパス(argv[1])を開いて読み取ってください。
書き込み後は必ずflush()することを忘れないでください(バッファリングによりデッドロックの原因になります)。
リアクティブ問題は純コード判定は行われません。
コミュニケーション問題に関して
コミュニケーション問題はリアクティブ形式の一種で、同じプログラムが2プロセスで動作します。
ジャッジコード(検証コード)が各プロセスの入出力をパイプで仲介し、プロセス間の通信を制御します。
パイプ構成
3形式で、ジャッジプロセスの標準入出力(FD0〜2)の扱いは以下の通り異なります。
| FD | スペシャルジャッジ (ファイル) | リアクティブ (リアルタイム) | コミュニケーション |
|---|---|---|---|
FD0 (stdin) | 解答プロセスの出力ファイル | 解答プロセスの stdout | プロセス1 の stdout |
FD1 (stdout) | ジャッジ出力 (自由) | 解答プロセスの stdin | プロセス1 の stdin |
FD2 (stderr) | 自由 | 自由 | 自由 |
FD3 | ― | ― | プロセス2 の stdout (ジャッジが読む) |
FD4 | ― | ― | プロセス2 の stdin (ジャッジが書く) |
スペシャルジャッジは解答プロセスが終了した後にその出力ファイルが FD0 に渡されるファイルベースの実行です。リアクティブはジャッジと解答プロセスが同時に走り、FD0/FD1 がそのままパイプで繋がるリアルタイム対話形式です。コミュニケーションはリアクティブの拡張で、プロセス1 とは FD0/FD1(リアクティブと同じ)、プロセス2 とは FD3/FD4 で通信します。テスト入力はいずれの形式も argv[1] から読み取ります。
コミュニケーション問題では、ジャッジプロセスに以下のファイルディスクリプタ(FD)が割り当てられます。
プロセス1 FD1 (stdout) ──→ FD0 (ジャッジが読み取る)
プロセス1 FD0 (stdin) ←── FD1 (ジャッジが書き込む)
プロセス2 FD1 (stdout) ──→ FD3 (ジャッジが読み取る)
プロセス2 FD0 (stdin) ←── FD4 (ジャッジが書き込む)
ユーザープロセス側から見ると通常通りの FD0/FD1 (stdin/stdout) です。ジャッジ側はプロセス1 とは標準入出力(FD0/FD1)で、プロセス2 とは FD3/FD4 で通信します。
| FD | 方向 | 接続先 | 用途 |
|---|---|---|---|
FD0 (stdin) | 読み取り | プロセス1 の stdout | プロセス1 が出力したデータをジャッジが読む |
FD1 (stdout) | 書き込み | プロセス1 の stdin | ジャッジからプロセス1 にデータを送る |
FD3 | 読み取り | プロセス2 の stdout | プロセス2 が出力したデータをジャッジが読む |
FD4 | 書き込み | プロセス2 の stdin | ジャッジからプロセス2 にデータを送る |
ジャッジコードは FD0/FD1(プロセス1)と FD3/FD4(プロセス2)で2つのユーザープロセスと通信します。
引数の形式はリアクティブと同じです。テスト入力ファイルが必要なら argv[1] を開いて読んでください。
ユーザープロセスは通常通り標準入力(stdin)から読み、標準出力(stdout)に書きます。
FD番号を意識するのはジャッジコード側のみです。
ジャッジコードの実装例(Python)
プロセス1 は標準入出力(FD0/FD1)、プロセス2 は FD3/FD4 を使います。プロセス1 は sys.stdin/sys.stdout でも、明示的に FD番号を指定する os.fdopen() でもどちらでも書けます。
書き方1: sys.stdin / sys.stdout を使う(リアクティブと同じスタイル)
import os, sys
# プロセス1: 標準入出力で通信
user1_read = sys.stdin # プロセス1の出力を読む
user1_write = sys.stdout # プロセス1に入力を送る
# プロセス2: FD3/FD4で通信
user2_read = os.fdopen(3, 'r') # プロセス2の出力を読む
user2_write = os.fdopen(4, 'w') # プロセス2に入力を送る
# テスト入力は argv[1] から
with open(sys.argv[1]) as f:
test_input = f.read()
user1_write.write("1 ...\n")
user1_write.flush()
user2_write.write("2 ...\n")
user2_write.flush()
書き方2: すべて os.fdopen() で揃える(プロセス2と書き方を統一)
import os, sys
# プロセス1・プロセス2 を同じスタイルで開く
user1_read = os.fdopen(0, 'r') # FD0: プロセス1の出力
user1_write = os.fdopen(1, 'w') # FD1: プロセス1への入力
user2_read = os.fdopen(3, 'r') # FD3: プロセス2の出力
user2_write = os.fdopen(4, 'w') # FD4: プロセス2への入力
with open(sys.argv[1]) as f:
test_input = f.read()
user1_write.write("1 ...\n")
user1_write.flush()
user2_write.write("2 ...\n")
user2_write.flush()
どちらも動作は同じです。sys.stdin は内部的に FD0 を指しているので、書き方1と書き方2は等価です。プロセス1 と プロセス2 の対称性を強調したい場合は書き方2、リアクティブとの一貫性を重視するなら書き方1を選ぶと良いでしょう。
コミュニケーション問題のジャッジコード実装では、以下の点に注意してください。
- プロセス1 とは標準入出力(FD0/FD1)、プロセス2 とは FD3/FD4 で通信する
- テスト入力は
argv[1]から読み取る(stdin はプロセス1 用に使用される) - 書き込み後は必ず
flush()する - 1つのプロセスが不正な出力をした場合、他のプロセスがデッドロックしないよう配慮する
- メモリ使用量は2つのユーザープロセスの最大値で判定される
- どちらかのユーザープロセスが異常終了した場合、その終了コードが使われる
コミュニケーション問題は純コード判定は行われません。
スコアについて(β)
問題編集ページで問題の種類として「スコア問題」を選択すると、問題ページ上部に「スコア順」のタブが現れます。「スコア順」タブはACになっている提出で、各ユーザーの最高点の提出(かつ提出IDが小さい提出)が表示されます。
スコア問題では、暫定的に提出制限を設けており、同じ問題の最後の提出(CE以外)から5分以内に提出できないようにしております。
この時に、スコアファイルに出力した値がスコアとして、各テストケースの合計として集計されます。
スコアファイルは、64ビット符号付き整数の値を出力してください。(末尾改行も許容)
(合計もオーバーフローしないように気をつけてください。)
64ビット整数値を使えますが、桁が多いと見にくいので多くても9桁あたりが望ましいと思います。
スコアを小さい順で表したいときは、その旨を問題文に明記して、マイナスをかけるといいかと思います。
大抵は何も意識せずにファイルを開き書き込めばいいと思いますが、「その他ユーザー」に書き込み権限を与えないように気をつけてください。
なお、「スコア問題」にすると自動的に「ACで公開」はしないになります。
スコア問題の難易度は0で良いと思います。
スコア問題は純コード判定は行われません。
提出するには、Twitter 、GitHub、 Googleもしくは右上の雲マークをクリックしてアカウントを作成してください。