昨夜の
AtCoder Beginner Contest 244のC問題はちょっと面白くて、通常の、処理すべきデータを標準入力から一気に全部読み込んで結果のデータを標準出力に全て書き出すタイプの問題ではなく、「インタラクティブ」な形式の問題だった。
ターン制のゲームのように、1つのケース中に何回も入力と出力を繰り返すのだ。その際、こちらの書き出したデータに応じて入力内容も変わるのである。
※「この問題はインタラクティブな問題(あなたの作成したプログラムとジャッジプログラムが入出力を介して対話を行う形式の問題)です。」と問題文に記載されていた。
このタイプの問題を解くのは僕は初めてだったのだが、注意事項として「出力を行うたびに標準出力をflushしてください。そうしなかった場合、ジャッジ結果がTLEとなる可能性があります。」とも記されていた。「TLE」とは「Time Limit Error」の略で、プログラム処理時間の制限時間内に処理が終わらなかったことを意味する「不正解」の一種。この問題の場合だと制限時間は2秒に設定されている。
僕はRubyで解いたのだが、普通に
puts x
とした(xは整数型の変数)だけでは、注意されていた通りにTLEになってしまった。調べてみるとRubyでは、グローバル変数$stdoutか組み込み定数STDOUTを用いて
$stdout.flush
あるいは、
STDOUT.flush
とすることによって、バッファ中の未書き出しのデータの書き出しを行うことができるようだ(「puts x」の次の行に「STDOUT.flush」を1行追加したところ、TLEにはならずに無事ACできた)。
また、事前に、
$stdout.sync = true
あるいは、
STDOUT.sync = true
としておけば、毎回のputsの度にflushが呼ばれるようになるらしいこともわかった。
本番終了後にGo言語で解き直してみたところ、Goでは単に
fmt.Println(x)
とするだけでもTLEにはならなかった。ただ、せっかくなので調べてみると、Flushメソッドをもつ
bufio.Writerが見つかった。
w := bufio.NewWriter(os.Stdout)
w.WriteString(fmt.Sprintln(x))
w.Flush()
2行目の部分は、
fmt.Fprintln(w, x)
とするのでも良いようだ。

0