D. Guess The Maximums(簡單二分)
思路:題意太迷惑了,它的意思是隻要找到一個滿足條件的數組即可,而不是要求跟預設的數字一模一樣,真實迷惑,顯然二分找到最大元素下標所在集合.
然後除了其他都爲最大元素,的求法就是所有集合去掉再詢問一次最大元素答案就是 。MDZZ
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
#define mst(a) memset(a,0,sizeof a)
int ask(vector<int>v){
cout<<"? "<<v.size()<<" ";
for(int i:v)
cout<<i<<" ";
cout<<endl;
int x;
cin>>x;
return x;
}
vector<int> get_set(vector<int>v,int n){
vector<int>s,vis(n+1);
for(auto i:v)
vis[i]=1;
for(int i=1;i<=n;i++) if(!vis[i]) s.push_back(i);
return s;
}
int main(){
int t,n,k,c;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
vector<vector<int> >S(k); //如果用了 resize()就不要用 push_back,不然會出錯。
for(int i=0;i<k;i++){
scanf("%d",&c);
for(int j=0,x;j<c;j++){
scanf("%d",&x);
S[i].push_back(x);
}
}
vector<int>query;
for(int i=1;i<=n;i++) query.push_back(i);
int mx=ask(query);
int l=0,r=k-1;
while(l<r){
int mid=(l+r)>>1;
vector<int>tmp;
tmp.clear();
for(int i=0;i<=mid;i++)
for(int j:S[i])
tmp.push_back(j);
int x=ask(tmp);
if(x==mx) r=mid;
else l=mid+1;
}
vector<int>ans(k),other;
other=get_set(S[l],n);
for(int i=0;i<k;i++){
if(l==i)
ans[i]=ask(other);
else ans[i]=mx;
}
cout<<"! ";
for(auto i:ans)
printf("%d ",i);
cout<<endl;
string jg;
cin>>jg;
}
return 0;
}