标签:
2 3 4 0 1 1 0 3 1 1 -1 0 0 1 1 0 -1
2 2
题意:在一个平面内有N个人,用一个W*H的矩形去围这些人(边上的也算), 求最大人数。
思路:以x从小到大排序,y值离散化,投影到y轴上,那么对于每个人的纵坐标,y,y+h就是
每个星星可以影响到的矩形 然后x,x+w+1就是一个进入事件和一个出去事件,其所带的值互
为相反数. node[1].val 保存当前的最大值 当所有的矩形都遍历一遍 取其中的最大值就是ans。
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn=20005; struct node { int x,y1,y2,val; void fun(int xx,int yy1,int yy2,int v) { x=xx,y1=yy1,y2=yy2; val=v; } }b[maxn]; struct tree { int l,r,add,val; }a[maxn*4]; int n,w,h,cnt,Y[maxn]; bool cmp(node p,node q) { return p.x<q.x; } void build(int l,int r,int k) { a[k].l=l,a[k].r=r; a[k].add=a[k].val=0; if(l==r) return ; int mid=(l+r)/2; build(l,mid,2*k); build(mid+1,r,2*k+1); } void pushdown(int k) { a[2*k].val+=a[k].add; a[2*k].add+=a[k].add; a[2*k+1].val+=a[k].add; a[2*k+1].add+=a[k].add; a[k].add=0; } void insert(int l,int r,int c,int k) { if(Y[a[k].l]==l && Y[a[k].r]==r) { a[k].val+=c; a[k].add+=c; } else { pushdown(k); int mid=(a[k].l+a[k].r)/2; if(Y[mid]>=r) insert(l,r,c,2*k); else if(Y[mid]<l) insert(l,r,c,2*k+1); else { insert(l,Y[mid],c,2*k); insert(Y[mid+1],r,c,2*k+1); } a[k].val=max(a[2*k].val,a[2*k+1].val); } } void input() { cnt=0; int x,y; scanf("%d %d",&w,&h); for(int i=0;i<n;i++) { scanf("%d %d",&x,&y); y+=20000; Y[cnt]=y; b[cnt++].fun(x,y,y+h,1); Y[cnt]=y+h; b[cnt++].fun(x+w+1,y,y+h,-1); } sort(Y,Y+cnt); sort(b,b+cnt,cmp); cnt=unique(Y,Y+cnt)-Y; } void solve() { build(0,cnt-1,1); int ans=0; for(int i=0;i<2*n;i++) { insert(b[i].y1,b[i].y2,b[i].val,1); ans=max(ans,a[1].val); } printf("%d\n",ans); } int main() { while(scanf("%d",&n)!=EOF) { if(n<0) break; input(); solve(); } return 0; }
hdu 5091 Beam Cannon(线段树+扫描线+离散化)
标签:
原文地址:http://blog.csdn.net/u012596172/article/details/42611311