题意:传送门
题解:根据题意可以直接看出使用二分来做,但是数据范围是
10000
10000
10000,二分
+
+
+判断下来复杂度为
O
(
n
2
∗
l
o
g
n
)
O(n^2*logn)
O(n2∗logn)肯定会
T
T
T,但是点的个数最多只给出
500
500
500个,就算各不相同,那么离散下来也就只有
1000
1000
1000,再算复杂度可以,然后就是将坐标离散化,进行前缀和,然后进行二分判定,判定中有个细节,就是草是在一个一个格子上的,所以细节需要多多调试。
c
o
d
e
:
code:
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#define pii pair<int,int>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int N=1010;
int c,n,sum[N][N];
pii points[N];
vector<int>numbers;
int get(int x){return lower_bound(numbers.begin(),numbers.end(),x)-numbers.begin();}
bool check(int len)
{
for(int x1=0,x2=1;x2<numbers.size();x2++){
while(numbers[x2]-numbers[x1+1]+1>len)x1++;
for(int y1=0,y2=1;y2<numbers.size();y2++){
while(numbers[y2]-numbers[y1+1]+1>len)y1++;
if(sum[x2][y2]-sum[x1][y2]-sum[x2][y1]+sum[x1][y1]>=c)return true;
}
}
return false;
}
int main()
{
c=read();n=read();
numbers.push_back(0);
for(int i=0;i<n;i++){
points[i].first=read();points[i].second=read();
numbers.push_back(points[i].first);numbers.push_back(points[i].second);
}
sort(numbers.begin(),numbers.end());
numbers.erase(unique(numbers.begin(),numbers.end()),numbers.end());
for(int i=0;i<n;i++){
int x=get(points[i].first),y=get(points[i].second);
sum[x][y]++;
}
for(int i=1;i<numbers.size();i++){
for(int j=1;j<numbers.size();j++){
sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
}
}
int l=1,r=10000;
while(l<r){
int mid=l+r>>1;
if(check(mid))r=mid;
else l=mid+1;
}
printf("%d\n",r);
return 0;
}