上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题。 最近学习了下线段树扫描线才发现确实是挺水的一道题。
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <string> #include <queue> #include <stdlib.h> using namespace std; #define N 10010 #define SN 500000 struct node { int x,y; }g[N]; int n,w,h; int l[SN],r[SN],mark[SN],num[SN];//肯定是要标号的 int cmp(node t,node t1) { return t.y<t1.y; } void build(int tl,int tr,int s) { l[s]=tl; r[s]=tr; mark[s]=0; num[s]=0; if(tl==tr) return ; int mid=(tl+tr)/2; build(tl,mid,2*s); build(mid+1,tr,2*s+1); } void up(int s) { if(mark[s]>0) { if(l[s]==r[s]) num[s]=mark[s]; else { num[s]=max(num[2*s],num[2*s+1])+mark[s]; } } else { if(l[s]==r[s]) num[s]=0; else num[s]=max(num[2*s],num[2*s+1]); } } void update(int tl,int tr,int sign,int s) { if(tl==l[s]&&tr==r[s]) { mark[s]+=sign; up(s); return ; } int mid=(l[s]+r[s])/2; if(tr<=mid) update(tl,tr,sign,2*s); else if(tl>mid) update(tl,tr,sign,2*s+1); else { update(tl,mid,sign,2*s); update(mid+1,tr,sign,2*s+1); } up(s); } int main() { while(scanf("%d",&n)&&n>=1) { scanf("%d%d",&w,&h); int mxx=-100000000,mix=100000000; for(int i=0;i<n;i++) { scanf("%d%d",&g[i].x,&g[i].y); g[i].x+=20020; g[i].y+=20020;//这个没有关系吧 mxx=max(mxx,g[i].x); mix=min(mix,g[i].x); } //又有负数 。。。 if(n==1) { printf("1 "); continue; } sort(g,g+n,cmp); int ans=1; build(mix,mxx+w,1); update(g[0].x,g[0].x+w,1,1); int i=0,j=1; while(1) { if(g[j].y-g[i].y<=h) //表示j这边还可以添加 { update(g[j].x,g[j].x+w,1,1); ans=max(ans,num[1]); j++; if(j>=n) break; } else { update(g[i].x,g[i].x+w,-1,1); i++; } } printf("%d ",ans); } return 0; }