zoukankan      html  css  js  c++  java
  • [Codeforces1491F]Magnets(交互)

    题面

    分析

    从小到大询问([1,i-1])(i),若答案不为0,则(i)为第二个有磁性的磁体。找到这个磁体后,我们可以对(i)后面的位置和(i)单独询问,进而得到后面的所有磁性
    然后在([1,i-1])中二分出第一个磁体的位置,剩下的都是没有磁性的。

    总询问次数为(n-1+ lceil log_2 n ceil leq n+lfloor log_2 n floor)

    代码

    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    int Ask(int fr,int ed,int pos){
    	int ans;
    	printf("? %d %d 
    ",ed-fr+1,1);
    	for(int j=fr;j<=ed;j++) printf("%d ",j);
    	printf("
    %d
    ",pos);
    	fflush(stdout);
    	scanf("%d",&ans);
    	return ans;
    }
    void print(vector<int>v){
    	printf("! %d
    ",(int)v.size());
    	for(int x : v) printf("%d ",x);
    	fflush(stdout);
    } 
    int T,n;
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		vector<int>ans;
    		scanf("%d",&n);
    		for(int i=2;i<=n;i++){
    			if(Ask(1,i-1,i)!=0){//找到第2个有磁性的位置 
    				//用这个磁体确定后面的磁性 
    				for(int j=i+1;j<=n;j++) if(Ask(i,i,j)==0) ans.push_back(j); 
    				int l=1,r=i-1,mid,pos=0;
    				while(l<=r){//找到第1个有磁性的位置 
    					mid=(l+r)>>1;
    					if(Ask(1,mid,i)!=0){
    						pos=mid;
    						r=mid-1;
    					}else l=mid+1;
    				}
    				for(int j=1;j<pos;j++) ans.push_back(j);
    				for(int j=pos+1;j<i;j++) ans.push_back(j);
    				print(ans);
    				break;
    			}
    		}
    	}
    }
    
    版权声明:因为我是蒟蒻,所以请大佬和神犇们不要转载(有坑)的文章,并指出问题,谢谢
  • 相关阅读:
    最长上升子序列(矩形嵌套)
    中国剩余定理模板poj1006
    POJ 2891 扩展欧几里德
    2015多校联赛第三场(部分题解)
    树链剖分
    深度理解链式前向星
    POJ 1228 Grandpa's Estate(凸包)
    旋转卡壳(一)
    最小圆覆盖 hdu 3007
    半平面求交 模板
  • 原文地址:https://www.cnblogs.com/birchtree/p/14463560.html
Copyright © 2011-2022 走看看