线段树+扫描线:
我们用矩形的中心点来描写叙述这个矩形,然后对于每一个敌舰,我们建立一个矩形中心的活动范围,即矩形中心在该范围内活动就能够覆盖到该敌舰.那么我们要求的问题就变成了:随意一个区域(肯定也是矩形的)最多能被矩形覆盖的最大值.
2 3 4 0 1 1 0 3 1 1 -1 0 0 1 1 0 -1
2 2
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
const int maxn=30100;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct SEG
{
double y1,y2,h;
int d;
}seg[maxn<<2];
bool cmp(SEG a,SEG b)
{
if(a.h==b.h) return a.d>b.d;
return a.h<b.h;
}
int add[maxn<<2],mx[maxn<<2];
int n,sn;
double W,H;
double Y[maxn<<2];
int ny;
void push_up(int rt)
{
mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
}
void push_down(int rt)
{
if(add[rt])
{
mx[rt<<1]+=add[rt]; mx[rt<<1|1]+=add[rt];
add[rt<<1]+=add[rt]; add[rt<<1|1]+=add[rt];
add[rt]=0;
}
}
void update(int L,int R,int D,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
add[rt]+=D;
mx[rt]+=D;
return ;
}
push_down(rt);
int m=(l+r)/2;
if(L<=m) update(L,R,D,lson);
if(R>m) update(L,R,D,rson);
push_up(rt);
}
int main()
{
while(scanf("%d",&n)!=EOF&&n>0)
{
scanf("%lf%lf",&W,&H);
sn=0; ny=0;
for(int i=0;i<n;i++)
{
double x,y;
scanf("%lf%lf",&x,&y);
seg[sn++]=(SEG){y-H/2,y+H/2,x-W/2,1};
seg[sn++]=(SEG){y-H/2,y+H/2,x+W/2,-1};
Y[ny++]=y-H/2; Y[ny++]=y+H/2;
}
sort(seg,seg+sn,cmp);
sort(Y,Y+ny);
ny=unique(Y,Y+ny)-Y;
memset(add,0,sizeof(add));
memset(mx,0,sizeof(mx));
int ans=0;
for(int i=0;i<sn;i++)
{
int y1=lower_bound(Y,Y+ny,seg[i].y1)-Y+1;
int y2=lower_bound(Y,Y+ny,seg[i].y2)-Y+1;
update(y1,y2,seg[i].d,1,ny,1);
ans=max(ans,mx[1]);
}
printf("%d\n",ans);
}
return 0;
}
原文:http://www.cnblogs.com/yangykaifa/p/7191765.html