実行時間制限: 5 sec / メモリ制限: 1024 MB
配点 : 点
問題文
これはインタラクティブな要素がある問題です。
Alice は から までの整数を並び替えた順列 を隠し持っています。隠し事が嫌いな Bob はなんとかしてこの順列を特定したいです。できるだけこの順列を隠したい Alice は順列のサイズ と以下の つのタイプの質問の答えのみを教えてくれます。
- タイプ : つの異なる整数 を選び、Alice に聞きます。すると、Alice は の つの整数の中央値を答えます。
- タイプ : つの異なる整数 を選び、Alice に聞きます。すると、Alice は の小さい方の添え字を答えます。つまり、 であれば , そうでなければ を答えます。
ただし、Alice はあまり順列の情報を与えたくないので、タイプ の質問には 回、タイプ の質問には 回しか答えません。さらに、Alice はいじわるなので、Bob のこれまでの質問に対する返答に矛盾しない範囲で順列の並びを途中で変えてしまうかもしれません。
Bob はとても忙しいので、熟考して質問することができません。Bob の代わりに、質問をして順列を当てるプログラムを作成し、彼を助けてください。
制約
部分点
- タイプ の質問の上限は 回、タイプ の質問の上限は 回である。この上限を超えて質問をした場合は Query Limit Exceeded となる。
- 質問回数が上限を超えず、かつ正しい順列を出力したとき、 点が得られる。
- タイプ の質問が 回以内、かつタイプ の質問が 回以内であり、さらに正しい順列を出力したとき、満点が得られる。
入出力
最初に順列のサイズ が 行で与えられる。
タイプ の質問をするときは次の形式に従って出力すること。
?
は から までの相異なる整数でなければならない。末尾には改行を出力すること。
タイプ の質問の答えは以下の形式で与えられる。
は から までの整数である。これは の つの整数の中央値である。
タイプ の質問をするときは次の形式に従って出力すること。
?
は から までの相異なる整数でなければならない。末尾には改行を出力すること。
タイプ の質問の答えは以下の形式で与えられる。
は または である。 であれば , そうでなければ が出力される。
タイプ の質問の上限は 回、タイプ の質問の上限は 回である。この上限を超えて質問をした場合は Query Limit Exceeded となる。
質問を何回かした後、順列を当てる必要がある。その際は次の形式に従って出力すること。
!
順列を出力した後、あなたのプログラムは直ちに終了しなければならない。終了しなかった場合のジャッジ結果は不定である。
また、これら以外のフォーマットで出力した場合のジャッジ結果も不定である。
各出力の後には、出力をフラッシュする必要があることに注意せよ。例えば、タイプ の質問をする際、 C では
printf("? 1 %d %d %d\n", i, j, k); fflush(stdout);
C++ では
cout<<"? 1 "<<i<<" "<<j<<" "<<k<<endl;
と出力すればよい。
順列は最初から固定されていないテストケースがあるので注意せよ。
入出力例
順列が "" である場合に、以下のような入出力が考えられる。
解答プログラムの出力 | 解答プログラムへの入力 | 説明 |
---|---|---|
順列のサイズ が入力として与えられる | ||
? | タイプ の質問をする、 の中央値を聞いている | |
の中央値は である | ||
? | タイプ の質問をする、 と ではどちらが小さいか聞いている | |
であるので、 が与えられる | ||
? | タイプ の質問をする、 の中央値を聞いている | |
の中央値は である | ||
! | 順列が "" であると回答している |
これは入出力の一つの例であり、意味のある入出力をしているとは限らない。