题目链接
学习了大佬题解,还是有点迷……有点不清醒,以后再看吧
#include<cstdio>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define pii pair<int,int>
#define PB(v) push_back(v)
#define MP(a,b) make_pair(a,b)
#define INF INT_MAX
const int N=1e3+10;
int c,n,sum[N][N];
vector<pii >p;
vector<int>X,Y;
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&c,&n);
int x,y;
_rep(i,1,n)scanf("%d%d",&x,&y),p.PB(MP(x,y)),X.PB(x),Y.PB(y);
sort(p.begin(),p.end());
sort(X.begin(),X.end());
sort(Y.begin(),Y.end());
X.erase(unique(X.begin(),X.end()),X.end());//去重
Y.erase(unique(Y.begin(),Y.end()),Y.end());//去重
x=X.size(),y=Y.size();
X.PB(INF),Y.PB(INF);
int pos=0;
_rep(i,1,x)_rep(j,1,y)
{
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
while(pos<n&&p[pos].first==X[i-1]&&p[pos].second==Y[j-1])sum[i][j]++,pos++;//判断是否有草
}
int ans=INF;
_for(i,0,x)//枚举起点x坐标
{
int i1=i+1;//终点x坐标
int s=0;//边长
int j=0;//起点y坐标
int j1=1;//终点y坐标
int v=sum[i1][j1]-sum[i][j1]-sum[i1][j]+sum[i][j];
while(1)
{
while(v<c&&(i1<x||j1<y))
{
s=min(X[i1]-X[i],Y[j1]-Y[j]);
while(X[i1]-X[i]<=s)i1++;
while(Y[j1]-Y[j]<=s)j1++;
v=sum[i1][j1]-sum[i][j1]-sum[i1][j]+sum[i][j];
}
if(v<c)break;//剪枝
ans=min(ans,s+1);
if(++j==y)break;
if(j1<=j)j1=j+1,s=0;
else s-=Y[j]-Y[j-1];//边长减少
while(X[i1-1]-X[i]>s)i1--;
v=sum[i1][j1]-sum[i][j1]-sum[i1][j]+sum[i][j];
}
}
printf("%d\n",ans);
return 0;
}