恶臭的交互题
/* 一个结论:一个矩形将空间分割成两部分,如果开头结尾都在一个部分内,那么穿过矩形边框的线条数就是偶数,反之就是奇数 通过这个结论来进行判断 先询问999次将两个x坐标确定,方法是询问(1,X)(n,X)如果结果是奇数,那么就有个点在这里,反之没有,或者是两个点都在X上 同理询问出两个y坐标 如果结果是两个x,两个y,那么需要确定是(x1,y1)(x2,y2)还是(x1,y2)(x2,y1),这个只要单点询问一次即可 如果结果是一个x,或者一个y(不可能出现两个x都相等,或者y都相等的情况)那么需要在二分再找一次x 在其中一条线上二分找一下就行了 */ #include<bits/stdc++.h> using namespace std; int ask(int x1,int y1,int x2,int y2){ cout<<"? "<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl; cout.flush(); int res; cin>>res; return res; cout.flush(); } int main(){ int x1=0,y1=0,x2=0,y2=0; int n;cin>>n; for(int i=1;i<=n;i++){ int res=ask(1,i,n,i); if(res%2){ if(y1)y2=i; else y1=i; } res=ask(i,1,i,n); if(res%2){ if(x1)x2=i; else x1=i; } } if(x1 && y1 && x2 && y2){ int res=ask(x1,y1,x1,y1); if(res%2) cout<<"! "<<x1<<" "<<y1<<" "<<x2<<" "<<y2; else cout<<"! "<<x1<<" "<<y2<<" "<<x2<<" "<<y1; return 0; } if(x1==0){ int l=1,r=n,mid,ans=1; while(l<=r){ mid=l+r>>1; if(ask(1,y1,mid,y1)%2)//如果[1,mid]是偶数 ans=mid,r=mid-1; else l=mid+1; } cout<<"! "<<ans<<" "<<y1<<" "<<ans<<" "<<y2<<endl; } else if(y1==0){ int l=1,r=n,mid,ans=1; while(l<=r){ mid=l+r>>1; if(ask(x1,1,x1,mid)%2)//如果[1,mid]是偶数 ans=mid,r=mid-1; else l=mid+1; } cout<<"! "<<x1<<" "<<ans<<" "<<x2<<" "<<ans<<endl; } }