POJ 3179 Corral the Cows

Corral the Cows
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 1352   Accepted: 565

Description

Farmer John wishes to build a corral for his cows. Being finicky beasts, they demand that the corral be square and that the corral contain at least C (1 <= C <= 500) clover fields for afternoon treats. The corral's edges must be parallel to the X,Y axes. 

FJ's land contains a total of N (C <= N <= 500) clover fields, each a block of size 1 x 1 and located at with its lower left corner at integer X and Y coordinates each in the range 1..10,000. Sometimes more than one clover field grows at the same location; such a field would have its location appear twice (or more) in the input. A corral surrounds a clover field if the field is entirely located inside the corral's borders. 

Help FJ by telling him the side length of the smallest square containing C clover fields.

Input

Line 1: Two space-separated integers: C and N 

Lines 2..N+1: Each line contains two space-separated integers that are the X,Y coordinates of a clover field.

Output

Line 1: A single line with a single integer that is length of one edge of the minimum size square that contains at least C clover fields.

Sample Input

3 4
1 2
2 1
4 1
5 2

Sample Output

4

Hint

Explanation of the sample: 

|*   *

| * *
+------
Below is one 4x4 solution (C's show most of the corral's area); many others exist. 

|CCCC

|CCCC
|*CCC*
|C*C*
+------

Source

 
 
题意:需要你搭建一个正方形的围栏,围栏里面需要有至少C个特殊的点,问你正方形最短的边长是多少
题解:给的坐标可能会重复,所以我们按照x坐标的和y坐标从小到大排序后离散化,用二维前缀和记录区域内点的个数,然后二分答案,每次检查时检查区域内的点是否满足大于C个即可
代码如下:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 510;
int C,n;
struct node{
    int x,y;
}p[maxn];
int xn,yn,rx[maxn],ry[maxn];
int sum[maxn][maxn];
bool cmp1(node a,node b){
    return a.x<b.x;
}
bool cmp2(node a,node b){
    return a.y<b.y;
}
bool check(int k){
    for(int a=1,b=1;;a++){
        while(rx[b+1]-rx[a]+1<=k&&b<xn) b++;
        for(int c=1,d=1;;c++){
            while(ry[d+1]-ry[c]+1<=k&&d<yn) d++;
            int ans=sum[b][d]+sum[a-1][c-1]-sum[a-1][d]-sum[b][c-1];
            if(ans>=C) return true;
            if(d==yn) break;
        }
        if(b==xn) break;
    }
    return false;
}

int main(){
    scanf("%d%d",&C,&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&p[i].x,&p[i].y);
    }
    sort(p+1,p+n+1,cmp1);
    xn=1;rx[1]=p[1].x;p[1].x=1;
    for(int i=2;i<=n;i++){
        if(p[i].x!=p[i-1].x) rx[++xn]=p[i].x;
        p[i].x=xn;
    }
    sort(p+1,p+n+1,cmp2);
    yn=1;ry[1]=p[1].y;p[1].y=1;
    for(int i=2;i<=n;i++){
        if(p[i].y!=p[i-1].y) ry[++yn]=p[i].y;
        p[i].y=yn;
    }
    for(int i=1;i<=n;i++) sum[p[i].x][p[i].y]++;
    for(int i=1;i<=xn;i++){
        for(int j=1;j<=yn;j++){
            sum[i][j]+=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1];
        }
    }
    int l=1,r=max(rx[xn],ry[yn]),ans;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid)){
            ans=mid;
            r=mid-1;
        }else{
            l=mid+1;
        }
    }
    printf("%d\n",ans);
}
View Code

 

posted @ 2018-08-18 16:13  buerdepepeqi  阅读(216)  评论(0编辑  收藏  举报