2023ccpc重庆站女生专场B.终焉之茧(交互题)

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 103x0,y0103

初始会给出终焉之茧与 [ 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)=(xx0)2+(yy0)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 2000dx,dy2000

思路

  • 根据 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 1000x,y1000,意味着每次可以到达平面任意一点。
  • 我们可以考虑分别二分 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;
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值