D. Guess The Maximums(簡單二分)

D. Guess The Maximums(簡單二分)

傳送門

思路:題意太迷惑了,它的意思是隻要找到一個滿足條件的數組PP即可,而不是要求跟預設的數字一模一樣,真實迷惑,顯然二分找到最大元素下標所在集合SS.

然後除了PiP_i其他都爲最大元素,PiP_i的求法就是所有集合去掉SiS_i再詢問一次最大元素答案就是PiP_iMDZZ

#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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章