• 2020牛客寒假算法基础集训营6 H 云


    https://ac.nowcoder.com/acm/contest/3007/H

    神思路。。。

    倘若两片云能够相遇,那么把他们映射到y=-x上的线段相交

    为什么?

    第一象限往下,第三象限往右他们最先相交的那两个点的初始位置和交点位置构成一个等腰直角三角形

    如果没有这样的等腰直角三角形则不能相交

    y=-x与该三角形底边垂直

    所以两点初始位置向y=-x作垂线,垂足重合

    如何将矩形映射到y=-x上?

    将左上角和右上角这两个点向y=-x作垂线,根据等腰直角三角形推一推可得垂足的纵坐标为(y-x)/2

    除以2会产生小数,不用除效果是一样的

    然后问题转化成有一些A类线段和一些B类线段,求AB相交的线段对数

    扫描线

    将线段的端点从小到大排序

    分别记录当前A类线段、B类线段个数

    碰到线段左端点,对应类别线段个数+1,并累加当前另一种类别线段的个数

    即每次累计左端点在该线段之前并与该线段相交的线段个数

    碰到线段右端点,对应类别线段个数-1

    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    
    #define N 100001
    
    struct node
    {
        int pos,lr,ty;
        node(int pos_=0,int lr_=0,int ty_=0) : pos(pos_),lr(lr_),ty(ty_) {}
    }e[N<<2]; 
    
    int cnt[N];
    
    bool cmp(node p,node q)
    {
        if(p.pos==q.pos && p.lr==q.lr) return p.ty<q.ty;
        if(p.pos==q.pos) return p.lr>q.lr;
        return p.pos<q.pos;
    }
    
    int main()
    {
        int n,m,xa,ya,xb,yb,tot=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
        {
            scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
            e[++tot]=node(yb-xb,1,0);
            e[++tot]=node(ya-xa,-1,0);
        }
        for(int i=1;i<=m;++i)
        {
            scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
            e[++tot]=node(yb-xb,1,1);
            e[++tot]=node(ya-xa,-1,1);
        }
        sort(e+1,e+tot+1,cmp); 
        long long ans=0;
        for(int i=1;i<=tot;++i)
        {
            cnt[e[i].ty]+=e[i].lr;
            if(e[i].lr==1)  ans+=cnt[e[i].ty^1];
        }
        printf("%lld",ans);
    } 
  • 相关阅读:
    在浏览器应用中使用 gRPC
    gRPC 客户端工厂集成
    gRPCurl 测试 gRPC 服务
    links
    Flex布局
    使用 IHttpClientFactory 实现复原 HTTP 请求
    Dex Common
    Dex MVVM
    日志
    配置
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12363408.html
Copyright © 2020-2023  润新知