BZOJ1720: [Usaco2006 Jan]Corral the Cows 奶牛围栏

此题非常一眼

就是直接分别将 x,y 坐标离散化

并在离散化之后做二维前缀和

二分一下答案,O(n^2) 的 check 即可

注意在 check 当中的二分 x - mid 的过程中,需要去二分 x - mid + 1
因为 STL lower_bound 是找大于等于参数的第一个数
如果直接二分 x - mid ,可能会找到想要的行的下一行

而二分 x - mid + 1 就不会出现这种问题
只需要在二分之后将得到的下标 -1 就行了

复杂度 O(n^2*log1e4)

网上好像有别的做法,懒得写了 = = ...


代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cstdio>
using namespace std;
 
const int MAXN = 505;
 
struct POS{
    int x, y, ux, uy;
    POS(int X = 0, int Y = 0) {x = X; y = Y;}
}pos[MAXN];
int n, c, sizx, sizy, maxp;
int unx[MAXN], uny[MAXN], sum[MAXN][MAXN];
 
inline bool chk(int mid) {
    for(int i = 1; i <= sizx; ++i) {
        register int dstx = lower_bound(unx + 1, unx + sizx + 1, unx[i] - mid + 1) - unx;
        for(int j = 1; j <= sizy; ++j) {
            register int dsty = lower_bound(uny + 1, uny + sizy + 1, uny[j] - mid + 1) - uny;
            if(sum[i][j] - sum[i][dsty - 1] - sum[dstx - 1][j] + sum[dstx - 1][dsty - 1] >= c) return true;
        }
    }
    return false;
}
inline void hfs(int l, int r) {
    int mid = 0, ans = 0;
    while(l <= r) {
        mid = ((l + r) >> 1);
        if(chk(mid)) {
            ans = mid;
            r = mid - 1;
        } else l = mid + 1;
    }
    printf("%d\n", ans);
    return;
}
 
int main() {
    scanf("%d%d", &c, &n);
    register int xx, yy;
    for(int i = 1; i <= n; ++i) {
        scanf("%d%d", &xx, &yy);
        pos[i] = POS(xx, yy);
        unx[i] = xx; uny[i] = yy;
        maxp = max(maxp, max(xx, yy));
    }
    sort(unx + 1, unx + n + 2); sort(uny + 1, uny + n + 2);
    sizx = unique(unx + 1, unx + n + 2) - unx - 1;
    sizy = unique(uny + 1, uny + n + 2) - uny - 1;
    for(int i = 1; i <= n; ++i) {
        pos[i].ux = lower_bound(unx + 1, unx + sizx + 1, pos[i].x) - unx;
        pos[i].uy = lower_bound(uny + 1, uny + sizy + 1, pos[i].y) - uny;
        ++sum[pos[i].ux][pos[i].uy];
    }
    for(int i = 1; i <= sizx; ++i) {
        for(int j = 1; j <= sizy; ++j) {
            sum[i][j] = sum[i][j] + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
        }
    }
    hfs(1, maxp);
    return 0;
}
posted @ 2018-10-02 19:14  EvalonXing  阅读(295)  评论(0编辑  收藏  举报