2023 c c p c 重庆站女生专场 B . 终焉之茧 \Huge{2023ccpc重庆站女生专场B.终焉之茧} 2023ccpc重庆站女生专场B.终焉之茧
题目链接:B. 终焉之茧
题意
给定一个无限大的平面,终焉之茧坐标为 [ x 0 , y 0 ] [x_0,y_0] [x0,y0],数据保证 − 1 0 3 ≤ x 0 , y 0 ≤ 1 0 3 -10^3\le x_0,y_0 \le 10^3 −103≤x0,y0≤103。
初始会给出终焉之茧与 [ 0 , 0 ] [0,0] [0,0]坐标的距离 f ( d ) = ( x − x 0 ) 2 + ( y − y 0 ) 2 f(d)=(x-x_0)^2+(y-y_0)^2 f(d)=(x−x0)2+(y−y0)2。
然后我们可以查询至多30次:
dx dy
:将当前坐标 [ x , y ] [x,y] [x,y]移动到 [ x + d x , y + d y ] [x+dx,y+dy] [x+dx,y+dy],然后会返回当前坐标距离终焉之茧的距离 f ( d ) f(d) f(d)。- 若距离 f ( d ) = 0 f(d)=0 f(d)=0时,表示找到终焉之茧,结束!
- − 2000 ≤ d x , d y ≤ 2000 -2000 \le dx,dy \le 2000 −2000≤dx,dy≤2000
思路
- 根据 x 0 , y 0 , d x , d y x_0,y_0,dx,dy x0,y0,dx,dy的数据范围,可知平面大小实际上为 − 1000 ≤ x , y ≤ 1000 -1000 \le x,y \le 1000 −1000≤x,y≤1000,意味着每次可以到达平面任意一点。
- 我们可以考虑分别二分 x , y x,y x,y,然后就可以在 2 × log 2 2000 2 \times \log_{2}{2000} 2×log22000次查询内找到终焉之茧。
标程
#define int long long
int nowx, nowy;
int ask(int x, int y) {
//因为查询时不是直接查坐标,而是移动距离,所以要减去当前坐标
cout << x - nowx << ' ' << y - nowy << endl; fflush(stdout);
nowx = x, nowy = y;
int z; cin >> z;
return z;
}
void Solved() {
int d, mid, l = -1000, r = 1000;
cin >> d;
if(!d) return;
int d1 = ask(-1000, 0);
if(!d1) return;
int d2 = ask(1000, 0);
if(!d2) return;
while(l < r) {//查找坐标x的位置
if(d1 < d2) {
mid = l + r >> 1;
d2 = ask(mid, nowy);
if(!d2) return;
r = mid;
} else if(d1 > d2) {
mid = l + r + 1 >> 1;
d1 = ask(mid, nowy);
if(!d1) return;
l = mid;
} else {
mid = l + r >> 1;
if(ask(mid, nowy) == 0) return;
break;
}
}
l = -1000, r = 1000;
d1 = ask(nowx, -1000);
if(!d1) return;
d2 = ask(nowy, 1000);
if(!d2) return;
while(l < r) {//查找坐标y的位置
if(d1 < d2) {
mid = l + r >> 1;
d2 = ask(nowx, mid);
if(!d2) return;
r = mid;
} else if(d1 > d2) {
mid = l + r + 1 >> 1;
d1 = ask(nowx, mid);
if(!d1) return;
l = mid;
} else {
mid = l + r >> 1;
if(ask(nowx, mid) == 0) return;
break;
}
}
}