思路:没三个连续的元素作为一组,查询
n
/
3
n/3
n/3次。在所有的结果中必定至少有一组的结果为0,且至少有一组的结果为1;
找到连续的两组(i,i+1,i+2),(i+3,i+4,i+5)满足前一组查询的结果为0,后一组查询的结果为1。然后查询(i+1,i+2,i+3),(i+2,i+3,i+4),根据以上四组结果的值我们可以在i-i+5的六个数中确定一个数一定为伪装者,确定另一个数为同伴。接下来尝试用每两次查询确定三个数的为伪装者还是同伴。根据之前n/3次查询的结果,我们再对每组数做两次额外的查询就可以确定这组数中每一个数是伪装者还是同伴。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int res[2000005],ans[2000005];
int ask(int x, int y, int z)
{
cout << "? " << x << ' ' << y << ' ' << z << endl;
cout.flush();
int t;
cin >> t;
return t;
}
void solve() {
int n;
cin >> n;
int a, b;
int pos;
for (int i = 1;i <= n;i += 3)
{
res[i] = ask(i, (i) % n + 1, (i + 1) % n + 1);
}
for (int i = 1;i <= n;i += 3)
{
if (res[i] == 0 && res[(i + 2) % n + 1])pos = i;
}
int x[4];
x[0] = res[pos];
x[1] = ask((pos) % n + 1, (pos + 1) % n + 1, (pos + 2) % n + 1);
x[2] = ask((pos + 1) % n + 1, (pos + 2) % n + 1, (pos + 3) % n + 1);
x[3] = res[(pos + 2) % n + 1];
for (int i = 0;i < 4;i++)
{
if (x[i] == 0 && x[(i + 1) % 4]==1)
{
if (i == 0)a = pos;
else a = (pos + i - 1) % n + 1;
if (i == 3)b = pos;
else b = (pos + (i + 1) % 4 + 1) % n + 1;
ans[a] = 0;
ans[b] = 1;
}
}
for (int i = 1;i <= n;i += 3)
{
if (i == a || i % n + 1 == a || (i + 1) % n + 1 == a || i==b || i % n + 1==b || (i + 1) % n + 1 == b)
{
if (i == a || i==b)
{
ans[i % n + 1] = ask(i % n + 1, a, b);
ans[(i + 1) % n + 1] = ask((i + 1) % n + 1, a, b);
}
if (i % n + 1 == a || i % n + 1==b)
{
ans[i] = ask(i, a, b);
ans[(i + 1) % n + 1] = ask((i + 1) % n + 1, a, b);
}
if ((i + 1) % n + 1 == a || (i + 1) % n + 1 == b)
{
ans[i] = ask(i, a, b);
ans[i % n + 1] = ask(i % n + 1, a, b);
}
}
else
{
int p, q;
if (res[i] == 0)
{
p = ask(i , i % n + 1, b);
if (p == 0)
{
ans[i] = ans[i % n + 1] = 0;
q = ask((i + 1) % n + 1, a, b);
ans[(i + 1) % n + 1] = q;
}
else
{
ans[(i + 1) % n + 1] = 0;
q = ask(i, a, b);
ans[i] = q;
ans[i % n + 1] = !q;
}
}
else
{
p = ask(i , i % n + 1, a);
if (p == 1)
{
ans[i] = ans[i % n + 1] = 1;
q = ask((i + 1) % n + 1, a, b);
ans[(i + 1) % n + 1] = q;
}
else
{
ans[(i + 1) % n + 1] = 1;
q = ask(i, a, b);
ans[i] = q;
ans[i % n + 1] = !q;
}
}
}
}
vector<int> v;
for (int i = 1;i <= n;i++)if (ans[i] == 0)v.push_back(i);
cout << "! " << v.size();
for (int i = 1;i <= v.size();i++)cout << ' ' <<v[i-1];
cout << endl;
cout.flush();
}
int main()
{
//ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T;
cin>>T;
while(T--)solve();
return 0;
}