题意:
这是一道交互题。
就是有n*n个点,有两个矩形,要你求两个矩形的左下角,和右上角。
你有不超过200次的询问机会,输出你询问的左下角,右上角(代表一个询问矩形),会得到一个回答。
回答是在你询问的这个矩形内,有几个完整的矩形(所求) 会得到1或2或0。
n<=216
sample
input
5
2
1
0
1
1
1
0
1
output
? 1 1 5 5
? 1 1 3 3
? 1 1 3 1
? 2 2 2 2
? 3 3 5 5
? 3 3 3 5
? 3 3 3 4
? 3 4 3 5
! 2 2 2 2 3 4 3 5
题解:
很明显,这是一道二分题,事实上,也是如此,它包含8个二分。
我们可以先确定第一个矩形的x2(右上角的横坐标) 如果返回是2则代表第二个矩形x4也缩小到mid了。。
在逐一确定其余三个点。
处理第二个矩形时,我们可能已经处理了一部分,这并不影响,但是,我们需要在确定第二个矩形的查询中,如果查询的矩形包含第一个矩形,则返回值-1。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int x1,y1,x2,y2,x3,y3,x4,y4,ok=0,step=0;
int a=1,b=1,c,d,last=2;
int chk(int x5,int y5,int x6,int y6){
if(a==x5&&b==y5&&c==x6&&d==y6)return last;
printf("? %d %d %d %d\n",x5,y5,x6,y6);
fflush(stdout);
step++;
int ans;
scanf("%d",&ans);
if(ok&&x5<=x1&&y5<=y1&&x6>=x2&&y6>=y2)ans--;
last=ans;
a=x5;b=y5;c=x6;d=y6;
return ans;
}
int main(){
int n;
scanf("%d",&n);
x1=x3=y1=y3=1;
x2=x4=y2=y4=n;
c=d=n;
int L=x1,R=x2;
while(L<=R){
int mid=L+R>>1;
int ans=chk(x1,y1,mid,y2);
if(ans==2){
x2=x4=mid;
R=mid-1;
}else if(ans==1){
x2=mid;
R=mid-1;
}else L=mid+1;
}
L=x1,R=x2;
while(L<=R){
int mid=L+R>>1;
int ans=chk(mid,y1,x2,y2);
if(ans==2){
L=mid+1;
x1=x3=mid;
}else if(ans==1){
L=mid+1;
x1=mid;
}else R=mid-1;
}
L=y1;R=y2;
while(L<=R){
int mid=L+R>>1;
int ans=chk(x1,y1,x2,mid);
if(ans==2){
y2=y4=mid;
R=mid-1;
}else if(ans==1){
R=mid-1;
y2=mid;
}else L=mid+1;
}
L=y1;R=y2;
while(L<=R){
int mid=L+R>>1;
int ans=chk(x1,mid,x2,y2);
if(ans==2){
y1=y3=mid;
L=mid+1;
}else if(ans==1){
y1=mid;
L=mid+1;
}else R=mid-1;
}
/*--------------------------------------------------*/
ok=1;
a=0;
L=x3,R=x4;
while(L<=R){
int mid=L+R>>1;
int ans=chk(x3,y3,mid,y4);
if(ans==1){
x4=mid;
R=mid-1;
}else L=mid+1;
}
L=x3,R=x4;
while(L<=R){
int mid=L+R>>1;
int ans=chk(mid,y3,x4,y4);
if(ans==1){
L=mid+1;
x3=mid;
}else R=mid-1;
}
L=y3;R=y4;
while(L<=R){
int mid=L+R>>1;
int ans=chk(x3,y3,x4,mid);
if(ans==1){
R=mid-1;
y4=mid;
}else L=mid+1;
}
L=y3;R=y4;
while(L<=R){
int mid=L+R>>1;
int ans=chk(x3,mid,x4,y4);
if(ans==1){
y3=mid;
L=mid+1;
}else R=mid-1;
}
printf("! %d %d %d %d %d %d %d %d %d\n",x1,y1,x2,y2,x3,y3,x4,y4,step);
return 0;
}