给一些点(<10000),求在W*H的矩形中能包含最多的点有多少。
2014上海邀请赛的题。
正解是线段树。
为什么不用?因为我傻。
用的O(n^2)暴力水过去的。由于水的姿势比较好还是记录一下。
离散化后将点加入每个点加入行的vector中,然后枚举矩形,
这样每次挪动矩形只要找到该行的一个范围[sx[k],ex[k]),而这个范围是递增的,所以平摊复杂度是O(n^2)。
要注意带注释的两句话,删掉可能会超时。
2014上海邀请赛的题。
正解是线段树。
为什么不用?因为我傻。
用的O(n^2)暴力水过去的。由于水的姿势比较好还是记录一下。
离散化后将点加入每个点加入行的vector中,然后枚举矩形,
这样每次挪动矩形只要找到该行的一个范围[sx[k],ex[k]),而这个范围是递增的,所以平摊复杂度是O(n^2)。
要注意带注释的两句话,删掉可能会超时。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<vector>
using namespace std;
#define NN 11000
vector<int> hy[NN];
int svx[NN*8],svy[NN*8];
int px[NN],py[NN],sx[NN],ex[NN],tot[NN];
struct point{int x, y;}p[NN];
int discret(int svx[],int tx,int px[]){
sort(px+1,px+tx+1);
int ret=unique(px+1,px+tx+1)-px-1;
int i;
for(i=1;i<=ret;++i){
svx[px[i]+21000]=i;
}
return ret;
}
void init(int n,int ty,int svy[]){
memset(tot,0,sizeof(tot));
int i,tmp;
for(i=1;i<=ty;++i) hy[i].clear();
for(i=1;i<=n;++i){
tmp=svy[p[i].y+21000];
hy[tmp].push_back(p[i].x);
}
int j;
for(i=1;i<=ty;++i){
sort(hy[i].begin(),hy[i].end());
tot[i]=hy[i].size();
}
}
int main(){
//freopen("1002in.txt","r",stdin);
int n,h,w,i,tx,ty;
int tsx,tex,tsy,tey,j,k,ttot,ans;
while(1){
scanf("%d",&n);
if (n<0) break;
scanf("%d%d",&w,&h);
h++;w++;
tx=0;ty=0;
for(i=1;i<=n;++i){
scanf("%d%d",&p[i].x,&p[i].y);
px[++tx]=p[i].x;
py[++ty]=p[i].y;
}
tx=discret(svx,tx,px);
ty=discret(svy,ty,py);
init(n,ty,svy);
memset(sx,0,sizeof(sx));
memset(ex,0,sizeof(ex));
ans=0;
for(i=1;i<=tx;++i){
tsx=px[i];
tex=tsx+w-1;
tey=1;
tsy=py[1];
ttot=0;
for(k=tey;k<=ty;++k){
if (py[k]-tsy+1>h) break;
while(sx[k]<tot[k]&&hy[k][sx[k]]<tsx) sx[k]++;
while(ex[k]<tot[k]&&hy[k][ex[k]]<=tex) ex[k]++;
ttot+=ex[k]-sx[k];
}
tey=k-1;
if (ttot>ans) ans=ttot;
for(j=2;j<=ty;++j){
ttot-=ex[j-1]-sx[j-1];
tsy=py[j];
if (tey<j) tey=j;
for(k=tey+1;k<=ty;++k){
if (py[k]-tsy+1>h) break;
while(sx[k]<tot[k]&&hy[k][sx[k]]<tsx) sx[k]++;
while(ex[k]<tot[k]&&hy[k][ex[k]]<=tex) ex[k]++;
ttot+=ex[k]-sx[k];
}
tey=k-1;
if (ttot>ans) ans=ttot;
if (tey==ty) break;//注意
}
if (tex>=px[tx]) break;//注意
}
printf("%d\n",ans);
}
return 0;
}