zoukankan      html  css  js  c++  java
  • [USACO12MAR] 花盆Flowerpot

    类型:二分+单调队列

    传送门:>Here<

    题意:给出$N$个点的坐标,要求根据$x$轴选定一段区间$[L,R]$,使得其中的点的最大与最小的$y$值之差$geq D$。求$Min{R-L}$

    解题思路

    一道单调队列的好题

    思想依然是转化。我们熟知的单调队列的作用也就是滑动窗口——定长区间滚动最大最小值

    但是现在区间长度不固定。容易发现,答案满足单调性的,于是可以二分答案。那么问题就转化为定长区间了。然后维护两个单调队列分别做最大与最小值即可

    Code

    /*By DennyQi 2018.8.18*/
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    #define  r  read()
    #define  Max(a,b)  (((a)>(b)) ? (a) : (b))
    #define  Min(a,b)  (((a)<(b)) ? (a) : (b))
    using namespace std;
    typedef long long ll;
    const int MAXN = 100010;
    const int INF = 1061109567;
    inline int read(){
        int x = 0; int w = 1; register int c = getchar();
        while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
        if(c == '-') w = -1, c = getchar();
        while(c >= '0' && c <= '9') x = (x<<3) + (x<<1) + c - '0', c = getchar();return x * w;
    }
    struct Coordinate{
        int x, y;
    }a[MAXN];
    int N,D,L,R,Mid,Ans,h1,h2,t1,t2;
    int qmax[MAXN],qmin[MAXN];
    inline bool cmp(const Coordinate& a, const Coordinate& b){
        return a.x < b.x;
    }
    inline bool judge(int len){
        h1 = h2 = 1, t1 = t2 = 0;
        qmax[0] = qmin[0] = 0;
        for(int i = 1; i <= N; ++i){
            while(h1 <= t1 && a[i].y > a[qmax[t1]].y){
                --t1;
            }
            qmax[++t1] = i;
            while(h2 <= t2 && a[i].y < a[qmin[t2]].y){
                --t2;
            }
            qmin[++t2] = i;
            while(h1 <= t1 && a[i].x - a[qmax[h1]].x > len){
                ++h1;
            }
            while(h2 <= t2 && a[i].x - a[qmin[h2]].x > len){
                ++h2;
            }
            if(a[qmax[h1]].y - a[qmin[h2]].y >= D) return 1;
        }
        return 0;
    }
    int main(){
        N = r, D = r;
        for(int i = 1; i <= N; ++i){
            a[i].x = r, a[i].y = r;
        }
        sort(a+1, a+N+1, cmp);
        Ans = -1;
        L = 1, R = 1e6+1;
        while(L <= R){
            Mid = (L + R) / 2;
            if(judge(Mid)){
                R = Mid - 1;
                Ans = Mid;
            }
            else{
                L = Mid + 1;
            }
        }
        printf("%d", Ans);
        return 0;
    }
  • 相关阅读:
    iOS去除导航栏和tabbar的横线
    各种坑
    iOS系统消息
    文件的读写
    MAC机中安装ruby环境--转载
    一句话处理服务器头像的尺寸
    开一个线程来处理 耗时的操作
    angular2中一种换肤实现方案
    一句话说明==和equals的区别
    下拉框样式在不同浏览器的简单兼容
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9499657.html
Copyright © 2011-2022 走看看