ツバサの備忘録

主に備忘録代わりに精進記録を載せていくつもりです。

AtCoder Petrozavodsk Contest 001 C - Vacant Seat

問題
提出コード

解法

インタラクティブ問題なので、二分探索を考えていきます。
まずは、どこか1つの席の情報がわかっていないと何も始まらないので、0番の席を特定します。
ここが空席ならばその時点で終了、女性だったならば、男性だった場合と真逆のことをかんがえればよいので、男性だった場合について考えていきます。
0番目が男性だった場合、1番、2番…の席に、男女交互に配置すると下の図のようになります。

f:id:emtubasa:20190426093452p:plain

ここで、青が男性、橙が女性を表します。
このままだと、図のように0N-1番目の席に座る人が、どちらも男性になってしまいます。
なので、これを回避するために、(0,N-1]区間のどこかしらに、空席が存在しているはずです。

次に、i番の席の情報を特定したとします。空席ならばその時点で操作が終わるので、それ以外について考えます。
上の図で割り振った男女男女…は、席の番号が偶数ならば男性、奇数ならば女性になっているはずです。
i番目の情報は、この偶奇に対する男女と一致しているか、していないかの2択です。

  • 一致している(iが奇数ならば男性、偶数ならば女性)場合
    この場合、0からiまでの席は、 空席が1つもなく、男女交互に座っている、もしくは空席が存在している、の2パターン存在しています。
    つまり、この部分は、空席が存在していない可能性があるので、この区間を今後探索するのは効率が悪そうです。
    一方、i+1からN-1までの席は、最初の状況と同じで、もし仮にi+1以降も男女交互で並んでいるとすると、N-10番目の席について矛盾が生じます。
    ということは、少なくとも1つはこの部分に空席が存在しているはずです。

f:id:emtubasa:20190426095142p:plain
i=3だった場合

よって、結局は(i+1,N-1]について、同じ探索を行えばよさそうです。

  • 一致してない(iが奇数ならば女性、偶数ならば男性)場合
    このパターンは先ほどと逆の状況になります。
    iからN-1区間は、男女交互に配置しても条件を満たすことができるため、空席が存在するかもしれませんし、存在しないかもしれません。
    逆に、1からi-1の部分については、男女交互に配置すると矛盾が生じるので、空席が確実に1つは存在します。

f:id:emtubasa:20190426095753p:plain

よって、こちらのパターンについては、(0,i-1]について同じ探索を行えばよさそうです。

上の状況を、どちらのパターンにころんでも効率よく行うために、i区間のちょうど真ん中にしてあげるとよいです。ということで、結果二分探索を行えばよいことになります。
結局、やることは

  1. 0番の席について調べる。調べるべき区間(0,N-1]とする。

  2. (l,r]について調べる。x = (l+r)/2についてクエリを出して、その部分が、仮にlから男女交互に配置していった場合の情報と一致するかどうかを調べる。一致したら、次に調べる区間(x,r]とし、そうでなければ(l,x-1]とする。空席が見つかるまでこれを繰り返す

ということを行えばよいです。

感想

久々のインタラクティブ問題でした。AtCoderだと初めてかもしれないです。
あんまり経験がないので、インタラクティブといえば二分探索っぽいことをしたくなります。そこから考察をさらっと終わらせたのはよかったのですが、例によってデバッグで時間をかけました。
xorを利用して条件の一致を判定したので、その部分を丁寧にやる必要がありましたね…