• Subway Pursuit (二分)(交互题)


    题目来源:codeforces1039B Subway Pursuit

    题目大意:
    在1到n里有一个运动的点,要求找到这个点,每次可以查询一个区间内有没有这个点,每次这个点往左或者往右移动1到k个位置,要求要在4500次查询内找到这个点的位置
    输入格式:
    一行两个整数n,k
    输出格式:
    每行输出两个整数l,r表示查询区间

    表示蒟蒻一直不知道交互题怎么做......而且看到原题的超长英文内心也是懵逼的......真的是什么都不会......

    最后终于会做了!(假的,其实是抄了题解啊)所以就特来写一篇博客记录一下。

    对于这个题呢,其实官方tutorial是这样说的:

    Notice that we can make segment in which we are located small enough using binary search. Let [l;r] be the last segment about which we knew for sure that train is in it (at the beginning it's [1;n]). Let m=l+r2. Let's ask about segment [l;m]. If we receive answer «YES», after this query train for sure will be in segment [l−k;m+k], otherwise in [m−k;r+k]. So, after each query length of segment is divided by 2 and increased by 2k. After segment length becomes irreducible (4k), let's ask about some random station in this segment. If we guessed right, let's finish the program, otherwise make the binary search again.
    To get the OK let's make one more observation: for all binary searches except the first one initial segment can be made [l−k;r+k]
    instead of [1;n].

    也就是二分的意思。

    因为每次一个区间分成两半,每一半的两端都会因为k的存在,而两端分别增加k个单位长度,也就是每一次增加4k个单位长度。

    那么在区间长度大于4k的时候我们显然可以二分处理,但是之后在区间长度小于等于4k的时候可以考虑使用随机化进行询问。

    题目要求我们在l==r且回答询问为True的时候结束程序,所以记得要及时判断is_solved变量并及时return掉。

    #include<iostream>
    #include<vector>
    #include<random>
    #include<ctime>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    bool is_solved = false;
    bool Request(long long a, long long b){
        cout<<a<<' '<<b<<endl;
        string answer;
        cin>>answer;
        if(answer=="Yes"&&a==b)
            is_solved=true;
        return answer=="Yes";
    }
    void Solve(long long n,int k){
        long long min_x=1,max_x=n;
        while (!is_solved){
            if (max_x-min_x<=k*4){
                if (k==0){
                    Request(min_x,max_x);
                    return;
                } 
                long long a=max_x-min_x+1;
                long long b=min_x+(((long long)rand()*rand())%a+a)%a;
                Request(b,b);
                if (is_solved)
                    return;
                min_x=max(min_x-k,(long long)1);
                max_x=min(max_x+k,n);
            }
            long long middle_x=(min_x + max_x)/2;
            if (Request(min_x,middle_x)){
                min_x=max((long long)1,min_x-k);
                max_x=min(middle_x + k,n);
            }
            else{
                min_x=max((long long)1,middle_x+1-k);
                max_x=min(n,max_x+k);
            }
        }
    }
    int main(){
        long long n;
        int k;
        cin >>n>>k;
        Solve(n,k);
    }
    
  • 相关阅读:
    用 jQuery 实现表单验证(摘抄)——选自《锋利的jQuery》(第2版)第5章的例题 5.1.5 表单验证
    js内置对象
    浅析js中的堆和栈
    深入理解js立即执行函数
    Javascript 中 null、NaN和undefined的区别
    javasript
    关于HTTP协议,一篇就够了
    ssh_maven之controller层开发
    ssh_maven之service开发
    ssh_maven的搭建之dao层的开发
  • 原文地址:https://www.cnblogs.com/fengxunling/p/9605647.html
Copyright © 2020-2023  润新知