【题意】给出坐标系中n个矩形,类型1的矩形每单位时间向x轴正方向移动1个单位,类型2的矩形向y轴正方向,初始矩形不重叠,一个点被矩形覆盖当且仅当它在矩形内部(不含边界),求$(-\infty ,+\infty)$时间内一个点被覆盖的最多矩形数量。n<=10^5。
【题解】不要被题目骗了,这题就是求若干横向矩形和若干纵向矩形之间是否有交,没有ans=1,有ans=2。
然后发现一横一竖相当于一个对另一个静止做斜向运动——所以两个矩形内部点有交当且仅当x+y的值相同。
然后一个矩形拆成x+y处+1和x+y+u+v处-1(注意是坐标系,不是网格图),然后就是区间上有若干A线段和若干B线段,判断是否有交了。
先排序(第二关键字 -1 优先),然后当某个点A和B的前缀和同时>0就有交。
复杂度O(n log n)。
#include<cstdio> #include<algorithm> int n,sum[2],T,X,Y,U,V,D,tot; struct cyc{int x,d,k;}a[200010]; bool cmp(cyc a,cyc b){return a.x<b.x||(a.x==b.x&&a.k<b.k);} int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n);tot=0; for(int i=1;i<=n;i++){ scanf("%d%d%d%d%d",&X,&Y,&U,&V,&D); a[++tot]=(cyc){X+Y,D,1}; a[++tot]=(cyc){X+Y+U+V,D,-1}; } std::sort(a+1,a+tot+1,cmp); sum[0]=sum[1]=0;int ans=1; for(int i=1;i<=tot;i++){ sum[a[i].d]+=a[i].k; if(sum[0]&&sum[1]){ans=2;break;} } printf("%d\n",ans); } return 0; }