2023年ccpc重庆站女生专场B
\(\Huge{2023ccpc重庆站女生专场B.终焉之茧}\)
题目链接:B. 终焉之茧
题意
给定一个无限大的平面,终焉之茧坐标为\([x_0,y_0]\),数据保证\(-10^3\le x_0,y_0 \le 10^3\)。
初始会给出终焉之茧与\([0,0]\)坐标的距离\(f(d)=(x-x_0)^2+(y-y_0)^2\)。
然后我们可以查询至多30次:
dx dy:将当前坐标\([x,y]\)移动到\([x+dx,y+dy]\),然后会返回当前坐标距离终焉之茧的距离\(f(d)\)。- 若距离\(f(d)=0\)时,表示找到终焉之茧,结束!
- \(-2000 \le dx,dy \le 2000\)
思路
- 根据\(x_0,y_0,dx,dy\)的数据范围,可知平面大小实际上为\(-1000 \le x,y \le 1000\),意味着每次可以到达平面任意一点。
- 我们可以考虑分别二分\(x,y\),然后就可以在\(2 \times \log_{2}{2000}\)次查询内找到终焉之茧。
标程
#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;
}
}
}

浙公网安备 33010602011771号