做法,
将读入的每个点(x,y)看做一个以该点为左上角宽W高H的矩形, 然后将矩形看做两条平行y轴(起点y-h,终点y)线,横坐标分别为 x , x+W;
然后可用经典的扫描线算法求解该题,即找出所有矩形重叠的最多次数,即所求值
证明 :
都在一个矩形内的点必定他们的上述规定的矩形都两两相交,而矩形两两相交必然有共同的交点是的所有矩形都相交于此;
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cctype>
#include <set>
using namespace std;
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1|1)
const int N = 81500;
const int maxn = 10010;
const int yadd = 61000;
int x[maxn],y[maxn],n,W,H;
struct segment{
int x,y1,y2,flag;
segment(int x,int y1,int y2,int f):x(x),y1(y1),y2(y2),flag(f){}
bool operator < (const segment& rhs) const {
return x < rhs.x || x == rhs.x && flag > rhs.flag;
}
};
vector<segment> ans;
int MAX[N<<2],col[N<<2];
void build(int l,int r,int rt){
MAX[rt]=col[rt]=0;
if(l==r) return;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void pushup(int rt){
MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}
void pushdown(int rt){
if(col[rt]!=0){
col[rt<<1]+=col[rt];
col[rt<<1|1]+=col[rt];
MAX[rt<<1]+=col[rt];
MAX[rt<<1|1]+=col[rt];
col[rt]=0;
}
}
int Ans,ql,qr,fff;
void update(int l,int r,int rt){
if(ql<=l&&r<=qr){
MAX[rt]+=fff;
col[rt]+=fff;
Ans= max(MAX[rt],Ans);
return ;
}
pushdown(rt);
int m=(l+r)>>1;
if(ql<=m) update(lson);
if(qr> m) update(rson);
pushup(rt);
}
int MAXS = 81250;
int main()
{
while(scanf("%d",&n)==1 && n!=-1){
scanf("%d %d",&W,&H);
int xx,yy;
ans.clear();
for(int i=1;i<=n;i++){
scanf("%d %d",&xx,&yy);
x[i]=xx;
y[i]=yy+yadd;
ans.push_back(segment(x[i],y[i],y[i]-H,1));
ans.push_back(segment(x[i]+W,y[i],y[i]-H,-1));
}
sort(ans.begin(),ans.end());
build(1,MAXS,1);
int res=0;
for(int i=0;i<ans.size();i++){
segment& temp = ans[i];
Ans=0;
ql=temp.y2,qr=temp.y1;
fff=temp.flag;
update(1,MAXS,1);
res=max(res,Ans);
}
printf("%d\n",res);
}
return 0;
}