2020年6月15日月曜日

CodeChef June Challenge 2020 - Guessing Game

guessg1

嘘がない場合と同様に、二分探索で範囲を狭めていけそう。まず、上図の[A]のように全体の1/2の位置にある数を尋ねてGと返ってきた状況を考える。(赤線とその隣にあるアルファベットが、質問した位置と答えを表す。LIEは「真の数を含んでいるとすると答えが嘘である」区間を表す。)その次に全体の1/4の位置にある数を尋ねると、二回連続で嘘をつけないという条件により、3段目で×をつけた区間は除外できる。同様に、1回目でLが返ってきた場合は3/4の位置にある数を尋ねると同等の結果が得られる。2回の質問で可能な空間のサイズが3/4になっているので、これを繰り返せば部分点が取れる。

満点の条件では120回の質問で突き止める必要があるが、上の方針では最終的な候補数が109×(3/4)603210^9 \times (3/4)^{60} \simeq 32程度にしかならない。そこで、上図の[B]のようにG→Lという答えが返ってきた場合に、追加で3/4の位置にある数を尋ねるとサイズが1/2になることに注目する。この比率が毎回達成できれば間に合う計算だが、G→Gの場合にうまい追加質問がない。つまり、この区間割ではできればG→L, L→Gと答えてほしくてG→G、L→Lは望ましくないということになるが、それは割り方が最適でないということを意味する。

そこで、区間の割り方を調整して、G→LでもG→Gでも同じレートで空間が縮むようにしたい。2回目の質問で1/4の代わりに位置x[0,1]x \in [0 ,1]で区切るとする。このとき、G→Lでは3回の質問で空間がx+1/4x+1/4倍になり、G→Gでは2回の質問で1x1-x倍になる。1回あたりの改善率が同じになる条件は(x+1/4)2=(1x)3(x+1/4)^2 = (1-x)^3なので、x0.31586x \simeq 0.31586と求まる。計算してみると、120回の質問で足りることがわかる。


想定解の改善率は2回あたり33%だった。2回の質問を1セットとして、G→Lの場合には次のセットで前の結果を利用できるらしい。