【POJ 3179】 Corral the Cows


【題目鏈接】

           http://poj.org/problem?id=3179

【算法】

           首先,我們發現答案是具有單調性的,也就是說,如果邊長為C的正方形可以,那么比邊長C大的正方形也可以,因此,可以二分答案

           那么,我們怎么檢驗呢?

           每個點的坐標最大時達到10000,因此,直接二維前綴和顯然是會超時的

           考慮將坐標離散化,然后求二維前綴和,由於N<=500,所以離散化后最多也只有1000個點

           檢驗時,我們枚舉正方形的左上角,用二分求出它的右下角,然后,判斷正方形內是否有大於C的草量

【代碼】

           

#include <algorithm>  
#include <bitset>  
#include <cctype>  
#include <cerrno>  
#include <clocale>  
#include <cmath>  
#include <complex>  
#include <cstdio>  
#include <cstdlib>  
#include <cstring>  
#include <ctime>  
#include <deque>  
#include <exception>  
#include <fstream>  
#include <functional>  
#include <limits>  
#include <list>  
#include <map>  
#include <iomanip>  
#include <ios>  
#include <iosfwd>  
#include <iostream>  
#include <istream>  
#include <ostream>  
#include <queue>  
#include <set>  
#include <sstream>  
#include <stdexcept>  
#include <streambuf>  
#include <string>  
#include <utility>  
#include <vector>  
#include <cwchar>  
#include <cwctype>  
#include <stack>  
#include <limits.h> 
using namespace std;
#define MAXN 510

int C,N,i,j,l,r,mid,ans,tx,ty,len;
int tmp[MAXN<<1],s[MAXN<<1][MAXN<<1],x[MAXN],y[MAXN];

inline int getsum(int xa,int ya,int xb,int yb)
{
        return s[xb][yb] - s[xa-1][yb] - s[xb][ya-1] + s[xa-1][ya-1];
}
inline bool check(int x)
{
        int i,j,tx,ty,pos;
        if (x > tmp[len]) 
    {
        if (s[len][len] >= C) return true;
        else return false;
    }
    pos = upper_bound(tmp+1,tmp+len+1,tmp[len]-x+1) - tmp - 1;
        for (i = 1; i <= pos; i++)
        {
                for (j = 1; j <= pos; j++)
                {
                        tx = upper_bound(tmp+1,tmp+len+1,tmp[i]+x-1) - tmp - 1;
                        ty = upper_bound(tmp+1,tmp+len+1,tmp[j]+x-1) - tmp - 1;
                        if (getsum(i,j,tx,ty) >= C) return true;        
                }        
        }                
        return false;
}

int main() 
{
        
        scanf("%d%d",&C,&N);
        for (i = 1; i <= N; i++)
        {
                scanf("%d%d",&x[i],&y[i]);    
                tmp[++len] = x[i];
                tmp[++len] = y[i];    
        }
        sort(tmp+1,tmp+len+1);
        len = unique(tmp+1,tmp+len+1) - tmp - 1;
        for (i = 1; i <= N; i++)
        {
                tx = lower_bound(tmp+1,tmp+len+1,x[i]) - tmp;
                ty = lower_bound(tmp+1,tmp+len+1,y[i]) - tmp;
                s[tx][ty]++; 
        }
        tmp[++len] = 10001;
        for (i = 1; i <= len; i++)
        {
                for (j = 1; j <= len; j++)
                {
                        s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + s[i][j];
                }
        }
        l = 1; r = 10000;
        while (l <= r)    
        {
                mid = (l + r) >> 1;
                if (check(mid))
                {
                        r = mid - 1;
                        ans = mid;
                } else l = mid + 1;
        }
        printf("%d\n",ans);
         
        return 0;
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM