zoukankan      html  css  js  c++  java
  • 8.10-Day1T2圈(circle)

    圈(circle)

    题目大意

    一开始看这道题,觉得有点像备用钥匙那道题,需要离散化,

    把一个球的两个点分开看...

    但是..其中的规律我推不出来

    (不是很难,只是蒟蒻好久都没有自己独立思考了)

    题解 

    题解给的是离散化+线段树...
    有一点点麻烦

    看到其他轻松切题的大佬的代码

    但关键部分的思想都是一样的

    如果一个圆被其他圆完全分割,则这个圆增加的块数为2,否则为1

    将所有圆按左端点从小到大排序,如果相同的话,就再按右端点从小到大排序

    那么遍历圆,如果它的左右两个点都没有或者有一个没有被遍历到的话,将其加入到map中

    如果都有被遍历到的话,那么他外面一定套着一个大的圆(于是当我这篇博客的时候我发现了问题...这个想法是错误的...我还是把它说完吧)对答案的贡献就+1。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    inline int read()
    {
        int sum = 0,p = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-')
                p = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (sum *= 10) += ch - '0';
            ch = getchar();
        }
        return sum * p;
    }
    
    const int N = 3000005;
    map<int,bool>p;
    ll ans,n;
    struct node
    {
        int l, r;
    } e[N];
    bool cmp(node x, node y)
    {
        if(x.l != y.l)
            return x.l < y.l;
        else
            return x.r < x.r;
    }
    int main()
    {
        freopen("circle.in","r",stdin);
        freopen("circle.out","w",stdout);
        n = read();
        ans = n + 1;
        for(int i = 1; i <= n; i++)
        {
            int x = read(),r = read();
            e[i].r = x + r;
            e[i].l = x - r;
        }
        sort(e + 1,e + n + 1,cmp);
        for(int i = 1; i <= n; i++)
        {
            if(p[e[i].l] && p[e[i].r])
                ans++;
            else
                p[e[i].l] = p[e[i].r] = 1;
        }
        printf("%lld
    ", ans);
        return 0;
    }
    错误算法

    hack数据:3 0 20 0 10 15 5

    还是安安心心看std吧

    在所有圆中,如果一个圆的半径小于等于另一个圆的半径则这个圆不会包含另一个圆 

    所以按圆的半径由小到大排序则前面的圆只能只能被后面的圆包含。因此只需统计当前的圆是否被前面的圆覆盖。

    因此先统计所有可能的区间将所有的点离散化,用线段数统计所有区间。每统计到下一个圆,先计算当前圆所包含的所有区间是否被完全覆盖。如果被完全覆盖,则答案+2。否则答案+1,然后将当前圆所包含的区间在线段树上标记。

    时间复杂度 O N log(N))。

    注意最后答案需要+1(最大区间)。

    (好好好麻烦...)

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    int n;
    struct cir
    {
        int r,pos;
    }a[310000];
    int has[610000],tmp[610000];
    int cnt,ans;
    int sum[2500000];
    int cmp(cir x,cir y)
    {
        return x.r<y.r;
    }
    void pushup(int x)
    {
        sum[x]=sum[x*2]&sum[x*2+1];
    }
    void pushdown(int x)
    {
        sum[x*2]|=sum[x];
        sum[x*2+1]|=sum[x];
    }
    void insert(int lq,int rq,int ln,int rn,int now)
    {
        if(has[ln]>=lq&&has[rn+1]<=rq)
        {
            sum[now]=1;
            return;
        }
        int mid=(ln+rn)>>1;
        if(has[mid]>=lq)
        insert(lq,rq,ln,mid,now*2);
        if(has[mid+1]<rq)
        insert(lq,rq,mid+1,rn,now*2+1);
        pushup(now);
    }
    int query(int lq,int rq,int ln,int rn,int now)
    {
        if(has[ln]>=lq&&has[rn+1]<=rq)
        return sum[now];
        pushdown(now);
        int mid=(ln+rn)>>1;
        int ret=1;
        if(has[mid]>=lq)
        ret&=query(lq,rq,ln,mid,now*2);
        if(has[mid+1]<rq)
        ret&=query(lq,rq,mid+1,rn,now*2+1);
        return ret;
    }
    int main()
    {
    //    freopen("circle.in","r",stdin);
    //    freopen("circle.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {    
            scanf("%d%d",&a[i].pos,&a[i].r);
            tmp[i*2-1]=a[i].pos-a[i].r;
            tmp[i*2]=a[i].pos+a[i].r;
        }
        sort(tmp+1,tmp+1+2*n);
        for(int i=1;i<=2*n;i++)
        {    
            if(tmp[i]!=tmp[i-1]||i==1)
            has[++cnt]=tmp[i];
        }
        sort(a+1,a+1+n,cmp);
        for(int i=1;i<=n;i++)
        {
            ans++;
            if(query(a[i].pos-a[i].r,a[i].pos+a[i].r,1,cnt-1,1))
            ans++;
            insert(a[i].pos-a[i].r,a[i].pos+a[i].r,1,cnt-1,1);
        }
        printf("%d",ans+1); 
    }
    幸福快乐std
  • 相关阅读:
    数字化工厂仿真系统-易景空间数字孪生工厂
    会议小程序-智能会议助手在会务系统中的优势
    商场室内地图制作-商场导航-智慧商业综合体
    室内定位室内导航到底能带来什么?
    医院导航系统-智慧医院室内导航-院内导航系统
    室内地图制作-首款实时室内绘制室内地图-3D室内地图
    城市综合三维管网管理-城市三维GIS管线系统-易景地图三维管线地图制作平台
    如何制作好看的室内地图-室内电子地图-在线制作室内地图
    jQuery ui中sortable draggable droppable的使用
    综合CSS3 transition、transform、animation写的一个动画导航
  • 原文地址:https://www.cnblogs.com/darlingroot/p/11331832.html
Copyright © 2011-2022 走看看