一般交互就跑不出二分。。
但是这题我看了半天才明白啥意思。。最后还fst了
发现有个地方多输出了点东西。。
第一次询问:最大值mx
后面十次询问:二分确定最大值所在位置x
最后一次询问:设x所在si,问出si对应的答案,其他位置的答案都是mx
#include<bits/stdc++.h> using namespace std; #define N 2005 int n,k,c[N],s[N][N]; int ask(int L,int R){ if(L>R)return 0; cout<<"? "; cout<<R-L+1<<" "; for(int i=L;i<=R;i++)cout<<i<<" "; cout<<endl; int res; cin>>res; return res; } int ask1(int x){ cout<<"? "<<n-c[x]<<" "; int tot=0,vis[N]={}; for(int i=1;i<=c[x];i++)vis[s[x][i]]=1; for(int i=1;i<=n;i++) if(!vis[i])cout<<i<<" "; cout<<endl; int res;cin>>res; return res; } int main(){ int t;cin>>t; while(t--){ cin>>n>>k; for(int i=1;i<=k;i++){ cin>>c[i]; for(int j=1;j<=c[i];j++) scanf("%d",&s[i][j]); } //问出最大值的下标 int L=1,R=n,mid,pos=n; int mx=ask(1,n); while(L<R){ mid=L+R>>1; int res=ask(L,mid); if(res==mx) R=mid; else L=mid+1; if(L==R){pos=L;break;} } int x,ans[N]; for(int i=1;i<=k;i++) for(int j=1;j<=c[i];j++) if(s[i][j]==pos)x=i; ans[x]=ask1(x); for(int i=1;i<=k;i++) if(i!=x)ans[i]=mx; cout<<"! "; for(int i=1;i<=k;i++)cout<<ans[i]<<" "; cout<<endl; string s; cin>>s; } }