Problem:
問題 G
XOR 回路
問題文
計算機科学実験及演習 3
は CAD を用いて CPU を設計する授業である．CPU は多くの回路を組み合わせなければ動かず，その中の 1 つに
n
ビット入力の XOR 回路がある．ここで XOR 回路とは，入力ビット列
x
1
x
2
...x
n
に対して，
x
1
+ x
2
+ ... + x
n
\ (mod 2)
を出力する回路のことを言う．しかし完璧に動作する XOR 回路を設計するのは時間がかかるので，とりあえず
n
ビットのうち
k
ビットだけ使う XOR 回路 A を作ることにした．つまり，ある
i
1
, ... , i
k
が存在し，回路 A は
x
i
1
+ x
i
2
+ ... + x
i
k
\ (mod 2)
を出力する．
暫く後に今度は
k
ビット入力の XOR 回路が欲しくなった．何だ簡単ではないか．先ほどの回路 A を使えばよい．ただ残念なことに，回路 A がどの
k
ビットを使っていたのか忘れてしまった上に，回路 A の設計図も間違って削除してしまった．しかしコンパイル済みの回路 A は残っている．なので，入力
x
1
x
2
...x
n
を入れて回路 A を実行することで，その出力
x
i
1
+ x
i
2
+ ... + x
i
k
\ (mod 2)
を見ることは出来る．
出来るだけ作業の時間を短くしたいので，回路 A の実行回数には上限を設定することにしよう．どうすれば回路Aが依存しているビット
i
1
, ... ,  i
k
を見つけられるだろうか？
入出力
最初に
n
と
k
がスペース区切りで与えられる．以降，プログラムは回路 A に入力を与え，その出力を読むことが出来る．例えば C/C++ で回路 A にビット列
x
1
x
2
...x
n
を与えるには
printf("?
x
1
x
2
...x
n
\n"); fflush(stdout);
とする．ここで各
x
i
の間にスペースをいれてはならない．
次に，
scanf("%d", &v);
とすると
v
に対応する出力
x
i
1
+ x
i
2
+ ... + x
i
k
\ (mod 2)
が入る．
最終的に回路 A が依存するビット
i
1
,...,i
k
を出力するには
printf("!
i
1
i
2
...i
k
\n"); fflush(stdout);
とする．ここで各
i
j
の間はスペースを丁度 1 つずついれる．
制約
1 ≤ n ≤ 10,000
1 ≤ k ≤ min(10, n)
各データセットごとに，回路 A の実行回数の上限は 200 回であり，それを超えると誤答 (
Query Limit Exceeded
) と判定される．
入出力例
入力例 1
以下の例はプログラムの入出力の例である．左の列はプログラムの出力，右の列はプログラムへの入力を時系列順に示している．最初に
n k
が入力として与えられる．ここでは
n = 2, k = 1
である．次に回路 A に
00
という入力をいれると，回路 A は
0
を返した．次に回路 A に
01
という入力をいれると，回路 A は再び
0
を返した．このことから回路 A は
1
ビット目のみ利用していることが分かり，プログラムは
1
を解答として出力した．
プログラムの出力
プログラムへの入力
2 1
?00
0
?01
0
!1
入力例 2
以下の例では，
n = 2, k = 2
であり，直ちに回路 A が
1
ビット目と
2
ビット目の両方を利用していることが分かる．よってプログラムは
1
と
2
を解答として出力した．
プログラムの出力
プログラムへの入力
2 2
!1 2

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

int n, k, qq[10005], ans[10005];

int ask(int lf = 0, int rg = n - 1){
    cout << "?";
    for(int i = 0; i < n; i ++)
        cout << ((lf <= i && i <= rg) ? qq[i] : 0);
    cout << endl;

    int rs; cin >> rs;
    return rs;
}

void print_ans(){
    cout << "!"; bool first = 0;
    for(int i = 0; i < n; i ++) if(ans[i]){
				if(i > 0) cout << " "; first = 1;
      			cout << i + 1;
    }
    cout << endl;

    exit(0);
}

int main(){
    srand(time(NULL));
    cin >> n >> k;

    if(n == k){
        for(int i = 0; i < n; i ++) ans[i] = 1;
        print_ans();
    }

    for(int times = 0; times < k; times ++){
        do{
            for(int i = 0; i < n; i ++)
                qq[i] = ans[i] ? 0 : (rand() & 1);
        }while(!ask());

        int lf = 0, rg = n - 1, rs = n;
        for(int md; lf <= rg;){
            md = (lf + rg) / 2;
            if(ask(lf, md)){
                rs = md;
                rg = md - 1;
            }
            else lf = md + 1;
        }

        ans[rs] = 1;
    }

    print_ans();
}
accuracy: 1
time_ms: 60
memory_kb: 3496
final_rank: 12

code_snippet: #include <iostream>
#include <cmath>
#include <numeric>
#include <algorithm>
#include <deque>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <map>
#include <stack>
#include <queue>
#include <functional>
#include <climits>
#include <numeric>
#include <bitset>
#include <random>
#include <tuple>
#include <initializer_list>
#include <fstream>

void ask(const std::vector<int>& bits, int from, int until) {
	std::cout << '?';
	for (auto i = 0; i < from; ++i) std::cout << '0';
	while (from < until) std::cout << bits[from++];
	for (auto i = until; i < bits.size(); ++i) std::cout << '0';
	std::cout << std::endl;
}

int main() {
	int n, k; std::cin >> n >> k;
	std::vector<int> bits(n), confirmed;
	std::mt19937 rand;
	while (confirmed.size() < k) {
		for (auto& b : bits) b = rand() & 1;
		for (const auto c : confirmed) bits[c - 1] = 0;
		ask(bits, 0, bits.size());
		int response; std::cin >> response;
		if (response == 0) continue;
		int min = 0, max = bits.size() ;
		while (min < max) {
			const auto mid = (min + max) / 2;
			if (mid == 0) {
				min = mid + 1; continue;
			}
			ask(bits, 0, mid);
			std::cin >> response;
			if (response == 1) {
				max = mid;
			}
			else {
				min = mid + 1;
			}
		}
		confirmed.push_back(max);
	}
	std::sort(confirmed.begin(), confirmed.end());
	std::cout << '!';
	for (auto i = 0; i < confirmed.size(); ++i) {
		if (i != 0) std::cout << ' ';
		std::cout << confirmed[i];
	}
	std::cout << std::endl;
}
accuracy: 1
time_ms: 70
memory_kb: 3256
final_rank: 11

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 10000;
const int MAX_K = 10;
const int MAX_Q = 200;

/* typedef */

typedef vector<int> vi;
typedef vector<long long> vl;
typedef vector<double> vd;
typedef pair<int,int> pii;
typedef pair<long,long> pll;
typedef long long ll;

/* global variables */

int n, k;
bool xs[MAX_N], used[MAX_N];

/* subroutines */

bool ask(int i0 = 0, int i1 = n) {
  putchar('?');
  for (int i = 0; i < n; i++)
    printf("%d", (i0 <= i && i < i1) ? xs[i] : 0);
  putchar('\n');

  int ans;
  cin >> ans;
  return (bool)ans;
}

void putans() {
  bool first = true;

  putchar('!');
  for (int i = 0; i < n; i++)
    if (used[i]) {
      if (i > 0) putchar(' ');
      printf("%d", i + 1);
    }
  putchar('\n');
  
}

/* main */

int main() {
  srand(time(NULL));

  cin >> n >> k;

  if (n == k) {
    for (int i = 0; i < n; i++) used[i] = true;
    putans();
    return 0;
  }
  
  memset(used, false, sizeof(used));
  int m = 0;

  while (m < k) {
    do {
      for (int i = 0; i < n; i++)
	xs[i] = used[i] ? 0 : (rand() & 1);
    } while (! ask());

    int i0 = 0, i1 = n;

    while (i0 + 1 < i1) {
      int im = (i0 + i1) / 2;
      if (ask(i0, im)) i1 = im;
      else i0 = im;
    }

    used[i0] = true;
    m++;
  }

  putans();
  
  return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 1296
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
template<class T> inline T sqr(T x) {return x*x;}

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;

#define all(a)  (a).begin(),(a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define pb push_back
#define mp make_pair
#define each(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define exist(s,e) ((s).find(e)!=(s).end())
#define range(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n)  range(i,0,n)
#define clr(a,b) memset((a), (b) ,sizeof(a))
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

const double eps = 1e-10;
const double pi  = acos(-1.0);
const ll INF =1LL << 62;
const int inf =1 << 29;

int n,k;

bool used[10010];

int check(string s){
	int l=0,r=n;
	while(r-l>1){

		int m=(l+r)/2;
		string next;

		for(int i=0;i<n;++i){
			if(l<=i&&i<m)
				next+=s[i];
			else
				next+="0";
		}

		printf("?%s\n",next.c_str());
		fflush(stdout);
		int res;
		scanf("%d",&res);

		if(res)
			r=m;
		else
			l=m;
	}
	return l;
}

int main(void){
	srand(time(NULL));
	scanf("%d %d",&n,&k);
	int num=0;
	while(num<k){
		string verify="";
		rep(i,n){
			if(used[i])
				verify+="0";
			else
				verify+=(rand()&1?"1":"0");
		}
		printf("?%s\n",verify.c_str());
		fflush(stdout);
		int res;
		scanf("%d",&res);

		if(res){
			used[check(verify)]=true;
			num++;
		}
	}
	string ans="";
	bool first=true;
	rep(i,n){
		if(used[i]){
			if(first)
				first=false;
			else
				ans+=" ";
			ans+=toString(i+1);
		}
	}
	printf("!%s\n",ans.c_str()); 
	fflush(stdout);
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 1308
final_rank: 6

code_snippet: #include<iostream>
#include<set>
#include<cstdlib>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

set<int> used;
int n, k;

void solve2(string str) {
  int cnt = 0;
  rep (i, n) if (str[i] == '1') ++cnt;
  if (cnt == 1) {
    rep (i, n) if (str[i] == '1') {
      used.insert(i);
      return;
    }
  }
  string s;
  rep (i, n) {
    if (str[i] == '1' && rand() % 2) s += "1";
    else s += "0";
  }
  cout << "?" + s << endl;
  cout.flush();
  int t;
  cin >> t;
  if (t == 1) {
    solve2(s);
  } else {
    rep (i, n) if (str[i] == '1') s[i] ^= '0' ^ '1';
    solve2(s);
  }
}

void solve() {
  while (true) {
    string str;
    rep (i, n) {
      str += rand() % 2 ? "1" : "0";
      if (used.count(i)) str[str.size() - 1] = '0';
    }
    cout << "?" + str << endl;
    cout.flush();
    int t;
    cin >> t;
    if (t == 1) {
      solve2(str);
      return;
    }
  }
}

int main() {
  cin >> n >> k;
  rep (i, k) solve();
  for (set<int>::iterator itr = used.begin(); itr != used.end(); ++itr) {
    if (itr == used.begin()) cout << "!";
    else cout << " ";
    cout << *itr + 1;
  }
  cout << endl;
}
accuracy: 1
time_ms: 80
memory_kb: 1772
final_rank: 9

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[100000];
int ret[10];
int val[10000];
int used[10000];
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	int at=0;
	if(a<200){
		for(int i=0;i<a;i++){
			for(int j=0;j<a;j++){
				if(i==j)str[j]='1';
				else str[j]='0';
			}
			printf("?%s\n",str);
			fflush(stdout);
			int c;
			scanf("%d",&c);
			if(c)ret[at++]=i+1;
		}
		printf("!");
		for(int i=0;i<b;i++){
			printf("%d",ret[i]);
			if(i<b-1)printf(" ");
			else printf("\n");
		}
		fflush(stdout);
		return 0;
	}
	for(int i=0;i<a;i++)val[i]=i;
	int n=a/2;
	for(int i=0;i<b;i++){
		int d=0;
		do{
			for(int j=0;j<50000;j++){
				int l=rand()%a;
				int r=rand()%a;
				int z=val[l];
				val[l]=val[r];
				val[r]=z;
			}
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<n;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
		}while(!d);
		int left=-1;
		int right=n+1;
		while(left+1<right){
			int M=(left+right)/2;
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<M;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
			if(d)right=M;
			else left=M;
		}
		int V=0;
		int P=0;
		for(int j=0;V<right;j++){
			if(!used[val[j]]){
			//	str[val[j]]='1';
				V++;P=j;
			}
		}
		used[val[P]]=1;
		ret[at++]=val[P]+1;
	}std::sort(ret,ret+b);
	printf("!");
	for(int i=0;i<b;i++){
		printf("%d",ret[i]);
		if(i<b-1)printf(" ");
		else printf("\n");
	}
	fflush(stdout);
}
accuracy: 1
time_ms: 110
memory_kb: 1296
final_rank: 8

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[100000];
int ret[10];
int val[10000];
int used[10000];
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	int at=0;
	if(a<200){
		for(int i=0;i<a;i++){
			for(int j=0;j<a;j++){
				if(i==j)str[j]='1';
				else str[j]='0';
			}
			printf("?%s\n",str);
			fflush(stdout);
			int c;
			scanf("%d",&c);
			if(c)ret[at++]=i+1;
		}
		printf("!");
		for(int i=0;i<b;i++){
			printf("%d",ret[i]);
			if(i<b-1)printf(" ");
			else printf("\n");
		}
		fflush(stdout);
		return 0;
	}
	for(int i=0;i<a;i++)val[i]=i;
	int n=a/2;
	for(int i=0;i<b;i++){
		int d=0;
		do{
			for(int j=0;j<50000;j++){
				int l=rand()%a;
				int r=rand()%a;
				int z=val[l];
				val[l]=val[r];
				val[r]=z;
			}
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<n;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
		}while(!d);
		int left=0;
		int right=n+1;
		while(left+1<right){
			int M=(left+right)/2;
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<M;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
			if(d)right=M;
			else left=M;
		}
		used[val[left]]=1;
		ret[at++]=val[left]+1;
	}std::sort(ret,ret+b);
	printf("!");
	for(int i=0;i<b;i++){
		printf("%d",ret[i]);
		if(i<b-1)printf(" ");
		else printf("\n");
	}
	fflush(stdout);
}
accuracy: 0.0975609756097561
time_ms: 70
memory_kb: 1280
final_rank: 17

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[100000];
int ret[10];
int val[10000];
int used[10000];
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	int at=0;
	if(a<200){
		for(int i=0;i<a;i++){
			for(int j=0;j<a;j++){
				if(i==j)str[j]='1';
				else str[j]='0';
			}
			printf("?%s\n",str);
			fflush(stdout);
			int c;
			scanf("%d",&c);
			if(c)ret[at++]=i+1;
		}
		printf("!");
		for(int i=0;i<b;i++){
			printf("%d",ret[i]);
			if(i<b-1)printf(" ");
			else printf("\n");
		}
		fflush(stdout);
		return 0;
	}
	for(int i=0;i<a;i++)val[i]=i;
	int n=a/2;
	for(int i=0;i<b;i++){
		int d=0;
		do{
			for(int j=0;j<50000;j++){
				int l=rand()%a;
				int r=rand()%a;
				int z=val[l];
				val[l]=val[r];
				val[r]=z;
			}
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<n;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
		}while(!d);
		int left=0;
		int right=n;
		while(left+1<right){
			int M=(left+right)/2;
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<M;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
			if(d)right=M;
			else left=M;
		}
		used[val[left]]=1;
		ret[at++]=val[left]+1;
	}std::sort(ret,ret+b);
	printf("!");
	for(int i=0;i<b;i++){
		printf("%d",ret[i]);
		if(i<b-1)printf(" ");
		else printf("\n");
	}
	fflush(stdout);
}
accuracy: 0.0975609756097561
time_ms: 60
memory_kb: 1280
final_rank: 14

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[100000];
int ret[10];
int val[10000];
int used[10000];
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	int at=0;
	if(a<200){
		for(int i=0;i<a;i++){
			for(int j=0;j<a;j++){
				if(i==j)str[j]='1';
				else str[j]='0';
			}
			printf("?%s\n",str);
			fflush(stdout);
			int c;
			scanf("%d",&c);
			if(c)ret[at++]=i+1;
		}
		printf("!");
		for(int i=0;i<b;i++){
			printf("%d",ret[i]);
			if(i<b-1)printf(" ");
			else printf("\n");
		}
		fflush(stdout);
		return 0;
	}
	for(int i=0;i<a;i++)val[i]=i;
	int n=a/2;
	for(int i=0;i<b;i++){
		int d=0;
		do{
			for(int j=0;j<50000;j++){
				int l=rand()%a;
				int r=rand()%a;
				int z=val[l];
				val[l]=val[r];
				val[r]=z;
			}
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<n;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
		}while(!d);
		int left=0;
		int right=n;
		while(left+1<right){
			int M=(left+right)/2;
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<M;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
			if(d)right=M;
			else left=M;
		}
		used[val[left]]=1;
		ret[at++]=val[left]+1;
	}
	printf("!");
	for(int i=0;i<b;i++){
		printf("%d",ret[i]);
		if(i<b-1)printf(" ");
		else printf("\n");
	}
	fflush(stdout);
}
accuracy: 0.0975609756097561
time_ms: 60
memory_kb: 1280
final_rank: 14

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[100000];
int ret[10];
int val[10000];
int used[10000];
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	int at=0;
	if(a<200){
		for(int i=0;i<a;i++){
			for(int j=0;j<a;j++){
				if(i==j)str[j]='1';
				else str[j]='0';
			}
			printf("?%s\n",str);
			fflush(stdout);
			int c;
			scanf("%d",&c);
			if(c)ret[at++]=i+1;
		}
		printf("!");
		for(int i=0;i<b;i++){
			printf("%d",ret[i]);
			if(i<b-1)printf(" ");
			else printf("\n");
		}
		fflush(stdout);
		return 0;
	}
	for(int i=0;i<a;i++)val[i]=i;
	int n=a/2;
	for(int i=0;i<b;i++){
		int d=0;
		do{
			for(int j=0;j<50000;j++){
				int l=rand()%a;
				int r=rand()%a;
				int z=val[l];
				val[l]=val[r];
				val[r]=z;
			}
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<n;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
		}while(!d);
		int left=0;
		int right=n;
		while(left+1<right){
			int M=(left+right)/2;
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<M;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
			if(d)right=M;
			else left=M+1;
		}
		used[val[left]]=1;
		ret[at++]=val[left]+1;
	}
	printf("!");
	for(int i=0;i<b;i++){
		printf("%d",ret[i]);
		if(i<b-1)printf(" ");
		else printf("\n");
	}
	fflush(stdout);
}
accuracy: 0.0975609756097561
time_ms: 70
memory_kb: 1280
final_rank: 17

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[100000];
int ret[10];
int val[10000];
int used[10000];
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	int at=0;
	if(a<200){
		for(int i=0;i<a;i++){
			for(int j=0;j<a;j++){
				if(i==j)str[j]='1';
				else str[j]='0';
			}
			printf("?%s\n",str);
			fflush(stdout);
			int c;
			scanf("%d",&c);
			if(c)ret[at++]=i+1;
		}
		printf("!");
		for(int i=0;i<b;i++){
			printf("%d",ret[i]);
			if(i<b-1)printf(" ");
			else printf("\n");
		}
		fflush(stdout);
		return 0;
	}
	for(int i=0;i<a;i++)val[i]=i;
	int n=a/2;
	for(int i=0;i<b;i++){
		int d=0;
		do{
			for(int j=0;j<50000;j++){
				int l=rand()%a;
				int r=rand()%a;
				int z=val[l];
				val[l]=val[r];
				val[r]=z;
			}
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<n;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
		}while(!d);
		int left=0;
		int right=n;
		while(left+1<right){
			int M=(left+right)/2;
			for(int j=0;j<a;j++)str[j]='0';
			int ind=0;
			for(int j=0;ind<M;j++){
				if(!used[val[j]]){
					str[val[j]]='1';
					ind++;
				}
			}
			printf("?%s\n",str);
			fflush(stdout);
			scanf("%d",&d);
			if(d)right=M;
			else left=M+1;
		}
		used[left]=1;
		ret[at++]=left+1;
	}
	printf("!");
	for(int i=0;i<b;i++){
		printf("%d",ret[i]);
		if(i<b-1)printf(" ");
		else printf("\n");
	}
	fflush(stdout);
}
accuracy: 0.0975609756097561
time_ms: 60
memory_kb: 1280
final_rank: 14

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

unsigned long xor128(){
    static unsigned long x=123456789,y=362436069,z=521288629,w=88675123;
    unsigned long t;
    t=(x^(x<<11));x=y;y=z;z=w; return( w=(w^(w>>19))^(t^(t>>8)) );
}

int n;

int func(bitset<10000> query)
{
    cout << '?';
    for(int i=0; i<n; ++i){
        if(query[i])
            cout << '1';
        else
            cout << '0';
    }
    cout << endl;

    int ret;
    cin >> ret;
    return ret;
}


int main()
{
    int k;
    cin >> n >> k;

    bitset<10000> ret;

    while(--k >= 0){
        int m = 0;
        bitset<10000> query;
        for(int i=0; i<n; ++i){
            query[i] = (xor128() % 2 == 1) && !ret[i];
            if(query[i])
                ++ m;
        }

        if(func(query) == 0){
            ++ k;
            continue;
        }

        while(m > 1){
            bitset<10000> query2;
            int m2 = 0;
            for(int i=0; i<n; ++i){
                if(query[i] && m2 < m / 2){
                    query2[i] = true;
                    ++ m2;
                }
            }

            if(func(query2) == 1){
                query = query2;
                m = m2;
            }else{
                query ^= query2;
                m -= m2;
            }
        }

        ret |= query;
    }

    bool first = true;
    for(int i=0; i<n; ++i){
        if(ret[i]){
            if(first){
                cout << '!' << (i+1);
                first = false;
            }else{
                cout << ' ' << (i+1);
            }
        }
    }
    cout << endl;

    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 860
final_rank: 4

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

bool ok[10000];
bool t[10000];

int n, k;

void get1() {
  memset(t,0,sizeof(t));
  while(1) {  
    REP(i,n) if (!ok[i]) t[i] = rand()%2;
    printf("?");
    REP(i,n) printf("%d",t[i]);
    puts(""); fflush(stdout);
    int v;
    scanf("%d",&v);
    if (v) return;
  }
}

bool check(int a, int b) {
  printf("?");  
  REP(i,n) printf("%d",(i>=a&&i<b)?t[i]:0);
  puts(""); fflush(stdout);
  int v;
  scanf("%d", &v);
  return v;
}

int main() {
  scanf("%d%d",&n,&k);
  vector<int> v;
  REP(i,k) {
    int a = 0, b = n;
    get1();
    while(a+1<b) {
      int mid = (a+b)/2;
      if (check(a, mid)) b = mid;
      else a = mid;
    }
    ok[a] = 1;
    v.push_back(a+1);
  }
  printf("!");
  REP(i,v.size()) {
    if (i) printf(" ");
    printf("%d", v[i]);
  }
  puts("");
  fflush(stdout);
}
accuracy: 1
time_ms: 170
memory_kb: 952
final_rank: 7

code_snippet: #include<cstdio>
#include<cstdlib>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

int dfs(int l,int r,int n,const int *bit){
	if(l==r-1) return l;

	putchar('?');
	rep(i,n){
		if     (l<=i && i<(l+r)/2) putchar('0'+bit[i]);
		else if(i<=(l+r)/2 && i<r) putchar('0');
		else                       putchar('0');
	}
	putchar('\n'); fflush(stdout);

	int v; scanf("%d",&v);
	return v?dfs(l,(l+r)/2,n,bit):dfs((l+r)/2,r,n,bit);
}

int main(){
	srand(777);
	int n,k; scanf("%d%d",&n,&k);
	int ans[10];
	rep(t,k){
		int bit[10000];
		while(1){
			putchar('?');
			rep(i,n){
				if(count(ans,ans+t,i)) bit[i]=0;
				else                   bit[i]=rand()&1;
				putchar('0'+bit[i]);
			}
			putchar('\n'); fflush(stdout);

			int v; scanf("%d",&v);
			if(v) break;
		}

		ans[t]=dfs(0,n,n,bit);
	}

	printf("!");
	rep(t,k) printf("%d%c",ans[t]+1,t<k-1?' ':'\n');

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 780
final_rank: 3

code_snippet: #include <cstdio>
#include <cstdlib>
#include <queue>
#include <ctime>
#define REP(i,n) for(int i=0; i<(int)(n); i++)

inline int getInt(){ int s; scanf("%d", &s); return s; }

using namespace std;

int x[10000];
int n, k;
int ans[10];

int query(){
  printf("?");
  REP(i,n) printf("%d", x[i]);
  printf("\n");
  fflush(stdout);
  return getInt();
}

int main(){
  srand(time(NULL));

  n = getInt();
  k = getInt();

  REP(i, k){
    do{
      // Random
      REP(j, n) x[j] = rand() % 2;
      REP(j, i) x[ans[j] - 1] = 0;
    }while(query() == 0);

    vector<int> ones;
    REP(j, n) if(x[j] == 1) ones.push_back(j);

    while(ones.size() != 1){
      int m = ones.size() / 2;

      REP(j, n) x[j] = 0;
      REP(j, m) x[ones[j]] = 1;

      if(query() == 1){
	ones = vector<int>(ones.begin(), ones.begin() + m);
      }else{
	ones = vector<int>(ones.begin() + m, ones.end());
      }
    }

    ans[i] = ones[0] + 1;
  }

  printf("!");
  REP(i,k) printf("%d%c", ans[i], i == k - 1 ? '\n' : ' ');
  fflush(stdout);

  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 924
final_rank: 5

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

int n, k;
bool exist[10010];
bool target[10010];
char output[10010];

int Communicate() {
  printf("%s\n", output);
  fflush(stdout);
  int v;
  scanf("%d", &v);
  return v;
}

int UpdateTarget(int c) {
  int index = -1;
  REP(i, n) {
    if (!target[i]) { continue; }
    if (output[i + 1] == '0' + c) { target[i] = false; }
    if (index == -2 || !target[i]) { continue; }
    else if (index == -1) { index = i; }
    else { index = -2; }
  }
  assert(index != -1);
  return index;
}

void RandomSequence() {
  output[0] = '?';
  REP(i, n) {
    if (!target[i]) { output[i + 1] = '0'; }
    else { output[i + 1] = '0' + (rand() % 2 ? 1 : 0); }
  }
  output[n + 1] = '\0';
}

int main() {
  scanf("%d %d", &n, &k);
  MEMSET(exist, false);
  REP(i, k) {
    REP(j, n) { target[j] = !exist[j]; }
    while (true) {
      RandomSequence();
      if (Communicate()) { break; }
    }
    int prev = 0;
    while (true) {
      int index = UpdateTarget(prev);
      if (index >= 0) {
        exist[index] = true;
        break;
      }
      RandomSequence();
      prev = Communicate() == 0 ? 1 : 0;
    }
  }

  vector<int> ans;
  REP(i, n) { if (exist[i]) { ans.push_back(i + 1); } }
  printf("!");
  REP(i, k) {
    if (i != 0) {
      putchar(' ');
    }
    printf("%d", ans[i]);
  }
  puts("");
  fflush(stdout);
}
accuracy: 1
time_ms: 30
memory_kb: 0
final_rank: 2

code_snippet: #include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

int main(){
  int n,k,v;
  int x[10000],a[10];
  bool use[10000];

  scanf("%d %d",&n,&k);

  if(n==k){
    for(int i=0;i<k;i++)a[i] = i;
  }else{
    for(int i=0;i<n;i++)use[i] = false;
    while(k--){
      for(int i=0;i<n;i++)x[i] = 1&i;
      while(1){
	bool f = true;
	for(int i=0;i<n;i++){
	  if(use[i] && x[i])f = false;
	}
	if(f){
	  printf("?");
	  for(int i=0;i<n;i++)printf("%d",x[i]);
	  printf("\n");
	  fflush(stdout);
	  scanf("%d",&v);
	  if(v)break;
	}
	random_shuffle(x,x+n);
      }
      vector<int> cand;
      for(int i=0;i<n;i++){
	if(x[i])cand.push_back(i);
      }

      while(cand.size()!=1){
	vector<int> c1,c2;
	for(int i=0;i<(int)cand.size()/2;i++)c1.push_back(cand[i]);
	for(int i=(int)cand.size()/2;i<(int)cand.size();i++)c2.push_back(cand[i]);
	cand.clear();

	for(int i=0;i<n;i++)x[i] = 0;
	for(int i=0;i<(int)c1.size();i++)x[c1[i]] = 1;

	printf("?");
	for(int i=0;i<n;i++)printf("%d",x[i]);
	printf("\n");
	fflush(stdout);
	scanf("%d",&v);
	if(v){
	  for(int i=0;i<(int)c1.size();i++)cand.push_back(c1[i]);
	}else{
	  for(int i=0;i<(int)c2.size();i++)cand.push_back(c2[i]);
	}
      }
      use[cand[0]] = true;
    }
    k = 0;
    for(int i=0;i<n;i++){
      if(use[i])a[k++] = i;
    }
  }

  printf("!%d",a[0]+1);
  for(int i=1;i<k;i++)printf(" %d",a[i]+1);
  printf("\n");
  fflush(stdout);
}
accuracy: 1
time_ms: 940
memory_kb: 940
final_rank: 13

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <stdio.h>
using namespace std;
#define rep(i,n) for(int i = 0 ; i < n ; i++)
int ac[10001];

int last = -1;
int suff[10001];
int N,K;

vector<int> answer(10);

string gen(vector<int> &g,int l,int r){
	string w = string(N,'0');
	for(int i = l ; i < r ; i++) if( !ac[ g[i] ] ) w[ g[i] ] = '1';
	return w;
}

string gen2(){
	string w = string(N,'0');
	for(int i = 0 ; i < N ; i++) if( !ac[i] ) w[i] = '0' + suff[i];
	return w;
}

int get(string s){
	cout << "?" << s << endl;
	fflush(stdout);
	int ans = 0;
	//rep(i,K) ans += s[answer[i]] - '0';
	cin >> ans;
	fflush(stdout);

	return ans%2;
}


int odd(vector<int> &g,int l ,int r){
	if(l+1 == r){
		ac[g[l]] = true;
		last = g[l];
		return 0;
	}
	int m = (l+r)/2;
	if( get(gen(g,l,m)) == 1){
		odd(g,l,m);
	}else{
		odd(g,m,r);
	}
}
int even(){
	for(int i = 0 ; i < 200 ; i++){
		if(get(gen2()) == 1) break;
		random_shuffle(suff,suff+N);
	}
	vector<int> a;
	string w = gen2();
	rep(i,N) if(w[i] == '1') a.push_back(i);
	odd(a,0,a.size());
}
int main(){
	int k;
	cin >> N >> k;
	//K = k;
	//rep(i,K) cin >> answer[i];
	vector<int> awawa;
	for(int i = 0 ; i < N ; i++) awawa.push_back(i);
	for(int i = 0 ; i < N ; i++) suff[i] = i%2;
	while(k){
		if(k%2){
			odd(awawa,0,awawa.size());
		}else{
			even();	
		}
		awawa.erase(remove(awawa.begin(),awawa.end(),last),awawa.end());
		k--;
	}
	vector<int> ans;
	rep(i,N) if(ac[i])ans.push_back(i+1);
	cout << "!";
	rep(i,ans.size()) cout << (i?" ":"") << ans[i];
	cout << endl;
	fflush(stdout);
}
accuracy: 1
time_ms: 20
memory_kb: 0
final_rank: 1