【LibreOJ】#6299. 「CodePlus 2018 3 月赛」白金元首与克劳德斯

【题意】给出坐标系中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;
}
View Code

 

posted @ 2018-03-05 22:00  ONION_CYC  阅读(86)  评论(1编辑  收藏