zoukankan      html  css  js  c++  java
  • $Poj3179 Corral the Cows$ 二分+离散化+二维前缀和

    Poj

    $Description$

    在一个二维平面上,有$N$颗草,每颗草的大小是$1*1$,左下角坐标为$x_i,y_i$.要求一个正方形,正方形的边平行于$x$或$y$轴,正方形里面包含至少$C$颗草.求正方形的最小边长.注意,同一个区域可能生长多颗草.

     数组范围:$1<=N,C<=500 1<=x_i,y_i<=10000$

    $Sol$

    最简单暴力的方法当然就是枚举正方形的一个顶点,就定为左上顶点叭,然后再从小到大枚举边长,然后$check()$,更新答案.显然这个方法复杂度爆炸$qwq$,而且,$check()$要用到二位前缀和,而根据$x,y$的范围,这根本就存不下.

    1.虽然$x,y$的范围很大,但是$N$只有$500$鸭,所以就离散化!

    2.发现合法的边长是单调的.如果当前边长可以,那么更大的显然也可以,所以二分就好了.

    觉得这里的离散化好妙.jpg

    特别要注意$lowerbound()$和$upperbound()$的区别吖!

    $Code$

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define il inline
    #define Rg register
    #define go(i,a,b) for(Rg int i=a;i<=b;++i)
    #define yes(i,a,b) for(Rg int i=a;i>=b;--i)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define db double
    using namespace std;
    il int read()
    {
        Rg int x=0,y=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        return x*y;
    }
    const int N=510;
    int n,c,as,b[N*2],ct,sum[N*2][N*2];
    struct node{int x,y;}a[510];
    il bool ck(int qvq)
    {
        if(qvq>=b[ct])return 1;
        Rg int ovo=upper_bound(b+1,b+ct+1,b[ct]-qvq+1)-b-1;
        go(i,1,ovo)
            go(j,1,ovo)
        {
            Rg int x=upper_bound(b+1,b+ct+1,b[i]+qvq-1)-b-1,y=upper_bound(b+1,b+ct+1,b[j]+qvq-1)-b-1;
            if(sum[x][y]-sum[i-1][y]-sum[x][j-1]+sum[i-1][j-1]>=c)return 1;
        }
        return 0;
    }
    int main()
    {
        c=read(),n=read();
        go(i,1,n)a[i].x=read(),a[i].y=read(),b[++ct]=a[i].x,b[++ct]=a[i].y;
        sort(b+1,b+ct+1);ct=unique(b+1,b+ct+1)-(b+1);b[++ct]=10001;
        go(i,1,n)
        {
            Rg int x=lower_bound(b+1,b+ct+1,a[i].x)-b,y=lower_bound(b+1,b+ct+1,a[i].y)-b;
            sum[x][y]++;
        }
        go(i,1,ct)go(j,1,ct)sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
        Rg int l=1,r=10010,mid;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(ck(mid))as=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%d
    ",as);
        return 0;
    }
    View Code

     

    光伴随的阴影
  • 相关阅读:
    MADDPG官方代码实现
    安装moviepy
    单目摄像机测距
    Tensorboard那些事
    instanceof、isPrototype、Object.create的区别
    鼠标事件以及clientX、offsetX、screenX、pageX、x的区别
    JS中的位置和宽度:clientWidth、offsetWidth、scrollWidth等区别
    vue项目build报错的解决办法(ERROR in static/js/vendor.xxxxx.js from UglifyJs)
    onclick(fn)与addEventListener("click", fn)的区别
    第五篇
  • 原文地址:https://www.cnblogs.com/forward777/p/11370415.html
Copyright © 2011-2022 走看看