[luoguP2862] [USACO06JAN]把牛Corral the Cows(二分 + 乱搞)

传送门

 

可以二分边长

然后另开两个数组,把x从小到大排序,把y从小到大排序

枚举x,可以得到正方形的长

枚举y,看看从这个y开始,往上能够到达多少个点,可以用类似队列来搞

 

其实发现算法的本质之后,x可以不用从小到大排序

#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 1001
#define max(x, y) ((x) > (y) ? (x) : (y))

int c, n, ans;
int x[N], y[N], a[N], b[N];

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
    for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
    return x * f;
}

inline bool cmp1(int a, int b)
{
    return x[a] < x[b];
}

inline bool cmp2(int a, int b)
{
    return y[a] < y[b];
}

inline bool check(int len)
{
    int i, j, k, l, r, sum;
    for(i = 1; i <= n; i++)
    {
        k = 1;
        sum = 0;
        l = x[a[i]];
        r = l + len - 1;
        for(j = 1; j <= n; j++)
        {
            while(y[b[k]] - y[b[j]] + 1 <= len && k <= n)
            {
                if(l <= x[b[k]] && x[b[k]] <= r) sum++;
                k++;
            }
            if(sum >= c) return 1;
            if(l <= x[b[j]] && x[b[j]] <= r) sum--;
        }
    }
    return 0;
}

int main()
{
    int i, l = 1, r, mid;
    c = read();
    n = read();
    for(i = 1; i <= n; i++)
    {
        x[i] = read();
        y[i] = read();
        r = max(r, x[i]);
        r = max(r, y[i]);
        a[i] = b[i] = i;
    }
    std::sort(a + 1, a + n + 1, cmp1);
    std::sort(b + 1, b + n + 1, cmp2);
    while(l <= r)
    {
        mid = (l + r) >> 1;
        if(check(mid)) ans = mid, r = mid - 1;
        else l = mid + 1; 
    }
    printf("%d\n", ans);
    return 0;
}

  

posted @ 2017-09-11 17:39  zht467  阅读(252)  评论(0编辑  收藏  举报