• bzoj 3718: [PA2014]Parking


    Description

    你的老板命令你将停车场里的车移动成他想要的样子。
    停车场是一个长条矩形,宽度为w。我们以其左下角顶点为原点,坐标轴平行于矩形的边,建立直角坐标系。停车场很长,我们可以认为它一直向右边伸展到无穷远处。
    车都是边平行于坐标轴的矩形,大小可能不同。你可以将车任意地平移(但不能旋转),只要他们不超出停车场的边界,且不能互相碰撞,但紧挨着是允许的(即任意时刻任两辆车的重叠面积为0)。
    你知道目前各辆车的摆放位置,以及老板心中所想的位置。你需要判断是否可以办到老板的任务。

    Input

    第一行为一个整数t(1<=t<=20),表示测试数据数量。
    对于每组测试数据,第一行两个整数n,w(1<=n<=50000,1<=w<=10^9),分别表示车的数量和停车场的宽度。
    接下来n行,第i行有四个整数x1,y1,x2,y2(0<=x1,x2<=10^9,0<=y1,y2<=w),表示编号为i的车的当前位置是由x1,y1,x2,y2确定的矩形。(注意:数据有可能出现x1>x2或y1>y2)
    再接下来n行,格式和意义同上,表示车的目标位置。

    Output

    输出t行,第i行为TAK(是)或NIE(否),表示第i组测试数据中能否按照要求进行移动。

    用三元组(a,b,c)表示一辆车的信息,其中a为初始x坐标,b为目标x坐标,c为|y1-y2|,那么不能完成任务当且仅当存在两个三元组(a,b,c),(d,e,f),满足a<d,b>e,c>w-f,于是可以按第一维排序,用树状数组维护第三维的值在第二维的前缀max(经典的扫描线求矩形内最大权点)

    #include<bits/stdc++.h>
    int _(){
        int x=0,c=getchar();
        while(c<48)c=getchar();
        while(c>47)x=x*10+c-48,c=getchar();
        return x;
    }
    int T,n,W,xs[50007],xp,bit[50007];
    struct ev{
        int x,y,z;
        bool operator<(ev w)const{return y>w.y;}
        void ins(){
            for(int w=x;w<=xp;w+=w&-w)if(bit[w]<z)bit[w]=z;
        }
        bool find(){
            int mx=W-z;
            for(int w=x-1;w;w-=w&-w)if(bit[w]>mx)return 1;
            return 0;
        }
    }e[50007];
    int min(int a,int b){return a<b?a:b;}
    int abs(int x){return x>0?x:-x;}
    int main(){
        for(T=_();T;--T){
            n=_();W=_();
            xp=0;
            for(int i=0;i<n;++i){
                int x1=_(),y1=_(),x2=_(),y2=_();
                xs[++xp]=e[i].x=min(x1,x2);
                e[i].z=abs(y1-y2);
            }
            std::sort(xs+1,xs+xp+1);
            for(int i=0;i<n;++i){
                e[i].x=std::lower_bound(xs+1,xs+xp+1,e[i].x)-xs;
            }
            for(int i=0;i<n;++i){
                int x1=_(),y1=_(),x2=_(),y2=_();
                e[i].y=min(x1,x2);
            }
            std::sort(e,e+n);
            memset(bit,0,sizeof(int)*(n+2));
            for(int i=0,j=0;i<n;i=j){
                for(;j<n&&e[i].y==e[j].y;++j);
                for(int k=i;k<j;++k)if(e[k].find())goto end;
                for(int k=i;k<j;++k)e[k].ins();
            }
            puts("TAK");continue;
            end:puts("NIE");
        }
        return 0;
    }
  • 相关阅读:
    C# 搜狗链接网址转换为真实网址
    C# 百度链接网址转换为真实网址
    RegexHelper
    IEnumerable<sting>串联成一个字符串
    List<T> 深度拷贝
    makecert.exe eku OID
    Wisej & MVC & WebApi 基架搭建
    彻底关闭Win10自动更新的代码
    SpringBoot-LayUI之性别展示
    【】SpringBoot-LayUI之动态表格
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6339914.html
Copyright © 2020-2023  润新知