#include <bits/stdc++.h>
using namespace std;
using Section = tuple<int, int, int>;
using Sections = vector<Section>;
void PrintAnswer(vector<int> &broken) {
const int n = broken.size();
sort(broken.begin(), broken.end());
for (int i = 0; i < n; ++i) {
cout << broken[i];
if (i != n - 1) cout << ' ';
}
cout << endl;
int verdict;
cin >> verdict;
if (verdict == -1) exit(0);
}
inline void change(char &c) { c = (c == '0' ? '1' : '0'); }
void Solve() {
int N, B, F, S;
cin >> N >> B >> F;
S = N - B;
Sections secs;
vector<int> broken;
string op, res;
char parity = '1';
for (int i = 0; i < N; i += B) {
op += string(min(N - i, B), parity);
change(parity);
}
cout << op << endl;
cin >> res;
parity = '1';
for (int i = 0, idx = 0; i < N; i += B) {
if (idx == S || res[idx] != parity) {
int num = 0;
for (int j = i; j < min(N, i + B); ++j) {
++num;
broken.push_back(j);
}
secs.emplace_back(Section(i, min(N, i + B), 0));
}
else {
int num = 0;
while (idx < S && res[idx] == parity && num < B) { ++num; ++idx; }
secs.emplace_back(Section(i, min(N, i + B), num));
}
change(parity);
}
if ((int)broken.size() == B) {
PrintAnswer(broken);
return ;
}
while ((int)broken.size() < B) {
op.clear();
parity = '1';
for (const auto &s : secs) {
const int len = get<1>(s) - get<0>(s);
const int num = get<2>(s);
if (num == 0 || num == len) {
op += string(len, parity);
change(parity);
}
else {
const int mid = (get<0>(s) + get<1>(s)) / 2;
op += string(mid - get<0>(s), parity);
change(parity);
op += string(get<1>(s) - mid, parity);
change(parity);
}
}
cout << op << endl;
cin >> res;
if (res == "-1") exit(0);
Sections nxt_secs;
parity = '1';
for (size_t i = 0, idx = 0; i < secs.size(); ++i) {
const int len = get<1>(secs[i]) - get<0>(secs[i]);
const int num = get<2>(secs[i]);
if (num == 0 || num == len) {
nxt_secs.emplace_back(secs[i]);
idx += num;
change(parity);
}
else {
const int mid = (get<0>(secs[i]) + get<1>(secs[i])) / 2;
int num_one = 0, num_zero = 0;
for (int j = 0; j < num; ++j) {
if (res[idx + j] == '0') ++num_zero;
else ++num_one;
}
idx += num;
Section s1(get<0>(secs[i]), mid, num_zero);
Section s2(mid, get<1>(secs[i]), num_one);
if (parity == '1') {
get<2>(s1) = num_one;
get<2>(s2) = num_zero;
}
change(parity);
change(parity);
nxt_secs.emplace_back(s1);
nxt_secs.emplace_back(s2);
if (get<2>(s1) == 0) {
for (int j = get<0>(s1); j < get<1>(s1); ++j) {
broken.push_back(j);
}
}
if (get<2>(s2) == 0) {
for (int j = get<0>(s2); j < get<1>(s2); ++j) {
broken.push_back(j);
}
}
}
}
secs = move(nxt_secs);
}
PrintAnswer(broken);
}
int main() {
int T;
cin >> T;
while (T--) Solve();
return 0;
}
ローカルでのテスト方法
ローカル環境でのテストのために testing_tool.py
というPython言語で書かれたプログラムが与えられる.作成したプログラムの実行ファイルを my_solution
として次を実行するとテストが行える.
testing_tool.py
は引数を1つ取り今回は 0 とする.mkfifo
コマンドで名前付きパイプ FIFO
を作成する.そして,python3 testing_tool.py 0
への標準入力を FIFO
から,標準出力をパイプ |
を用いて実行ファイル ./my_solution
への標準入力へとリンクしている.また,./my_solution
の標準出力を FIFO
へリンクしている.このようにすることでプロセス間通信が行えて,インタラクティブ問題のテストが行える.
$ mkfifo FIFO
$ python3 testing_tool.py 0 < FIFO | ./my_solution > FIFO
他の方法として,nico_shindanninさんのツイートが参考になる.