题意:有n个人,其中有n/3~2*n/3个狼人,可以询问2n次,每次三个人,返回狼人多还是好人多。
解法:按1,2,3和2,3,4和3,4,5........这样询问下去,当出现上一次询问结果和这一次结果不一样时,
说明中间两个人一个好人,一个狼人(可以举例证明),用这两个人可以得出其他所有人的身份,最后再取两个身份不同的询问这两个人即可
#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
int a[20005];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t, n;
cin >> t;
while (t--) {
cin >> n;
int a1=-1, a2=-1,b1=0,b2=0;
for (int i = 1; i <= n; i ++) {
int res;
cout << '?' << ' ' << i << ' ' << i + 1 << ' ' << i + 2 << endl;
cin >> res;
if (a1 != res&&a1!=-1) {
a1 = i , a2 = i + 1; break;
}
a1 = res;
}
for (int i = 1; i <= n; i++) {
if (i == a1 || i == a2)continue;
cout << '?' << ' ' << a1 << ' ' << a2 << ' ' << i << endl;
cin >> a[i];
if (a[i] == 1 && b1 == 0)b1 = i;
else if (a[i] == 0 && b2 == 0)b2 = i;
}
cout << '?' << ' ' << a1 << ' ' << b2 << ' ' << b1 << endl;
cin >> a[a1];
cout << '?' << ' ' << a2 << ' ' << b2 << ' ' << b1 << endl;
cin >> a[a2];
cout << "!";
int res = 0;
for (int i = 1; i <= n; i++)if(!a[i])res ++;
cout << ' ' << res;
for (int i = 1; i <= n; i++) {
if (a[i]==0)cout << ' ' << i;
}
cout << endl;
}
return 0;
}