CodeForces 思維題集錦 #2 - 809B (2200)

原題鏈接:809B Glad to see you! (binary search, interactive, *2200)

題意簡述

交互題,長度為 n 的數(shù)列選中了 k 個位置,可以指定 x,y 詢問 x 到最近的選中的位置的距離是否小于等于 y 到最近的選中的位置的距離,需要在 60 次詢問內(nèi)得到任意兩個選中的位置。

解法分析

n\le 10^5,詢問不超過 60 次,明示二分(事實(shí)上算法標(biāo)簽也是這樣)。

考慮在 \left[1,n\right] 中二分詢問 mid,mid+1,根據(jù)題意,當(dāng)?shù)玫娇隙ńY(jié)果 TAK 的時候,在左側(cè)必然有一個選中的位置,反之同理。

這樣二分的結(jié)果就是第一個位置 x

那么第二個位置怎么得到呢?繼續(xù)在 \left[1,n\right] 中二分顯然是不行的,將會得到相同的結(jié)果。不過我們可以嘗試在 \left[1,x-1\right] 中二分。但是如果第一次二分得到的 x 是最左側(cè)的選中的位置,在這個范圍內(nèi)沒有答案怎么辦呢?沒關(guān)系,60 大約是 \log_210^5 的三倍,我們還可以在 \left[x+1,n\right] 再次二分。

最后一個細(xì)節(jié):怎么判斷在左側(cè)是否有解呢?如果二分的結(jié)果與第一次得到的 x 相等,顯然得到了一個假的(重復(fù)的)解,此時在左側(cè)無解。同時,因?yàn)?x 是一個選中的位置,它的距離永遠(yuǎn)是 0,因此如果詢問 y,x 得到 NIE 就說明 y 的距離大于 0,即 y 不是一個解。

代碼

//By: Luogu@rui_er(122461)
#include <bits/stdc++.h>
#define loop while(true)
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
#define fil(x,y) memset(x, y, sizeof(x))
#define mulT0 int T; for(scanf("%d", &T);T;T--)
#define mulT1 int T, rnds; for(scanf("%d", &T),rnds=1;rnds<=T;rnds++)
using namespace std;
typedef long long ll;

int n, k, x, y;
bool interact(int x, int y) {
    printf("1 %d %d\n", x, y);
    fflush(stdout);
    char c[4];
    scanf("%s", c);
    return c[0] == 'T';
}
void give(int x, int y) {
    printf("2 %d %d\n", x, y);
    fflush(stdout);
}
int binarySearch(int l, int r) {
    while(l < r) {
        int mid = (l + r) >> 1;
        if(interact(mid, mid+1)) r = mid;
        else l = mid + 1;
    }
    return l;
}

int main() {
    scanf("%d%d", &n, &k);
    x = binarySearch(1, n);
    y = binarySearch(1, x-1);
    if(!(x ^ y) || !interact(y, x)) y = binarySearch(x+1, n);
    give(x, y);
    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容