zoukankan      html  css  js  c++  java
  • POJ1151基本的扫描线求面积

    题意:
         给定n个矩形的对角坐标,分别是左下和右上,浮点型,求矩形覆盖的面积。


    思路:

          基本的线段树扫描线求面积,没有坑点,不解释了,提示一点,有的题尤其是线段树扫描线的题需要离散化的时候建议二分去找,别map,记得之前map超时过很多次,但不是针对这个题目,这个题数据量不大,怎么都行,发现codeblock这个编译器定义宏然后在定义结构体的时候变量名字相同导致编译不过去,我之前用的DEV也是这么写的,记得能编译过去,不知道为啥。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    
    //#define l ,mid ,t << 1
    //#define mid ,r ,t << 1 | 1
    #define N 105
    
    using namespace std;
    
    typedef struct
    {
      double l ,r ,h ,mk;
    }EDGE;
    
    double num[105*2*2] ,tmp[105*2*2];
    double len[105*2*2*4];
    int cnt[105*2*2*4];
    EDGE E[105*2];
    
    bool camp(EDGE a ,EDGE b)
    {
        return a.h < b.h || a.h == b.h && a.mk < b.mk;
    }
    
    void PushUp(int l ,int r ,int t)
    {
        if(cnt[t]) len[t] = num[r] - num[l];
        else if(l + 1 == r) len[t] = 0;
        else len[t] = len[t<<1] + len[t<<1|1];
    }
    
    void Update(int l ,int r ,int t ,int a ,int b ,int c)
    {
        if(a == l && b == r)
        {
            cnt[t] += c;
            PushUp(l ,r ,t);
            return ;
        }
        int mid = (l + r) >> 1;
        if(b <= mid) Update(l,mid ,t << 1 ,a ,b ,c);
        else if(a >= mid) Update(mid ,r ,t << 1 | 1 ,a ,b ,c);
        else
        {
            Update(l ,mid ,t << 1 ,a ,mid ,c);
            Update(mid ,r ,t << 1 | 1 ,mid  ,b ,c);
        }
        PushUp(l ,r ,t);
    }
    
    void BuidTree()
    {
        memset(cnt ,0 ,sizeof(cnt));
        memset(len ,0 ,sizeof(len));
        return ;
    }
    
    int search2(double now ,int n)
    {
        int low = 1 ,up = n ,mid ,ans;
        while(low <= up)
        {
            mid = (low + up) >> 1;
            if(now <= num[mid])
            {
                ans = mid;
                up = mid - 1;
            }
            else low = mid + 1;
        }
        return ans;
    }
    
    
    
    int main ()
    {
        int i ,n ,id ,cas = 1;
        double x1 ,y1 ,x2 ,y2;
        double Ans;
        while(~scanf("%d" ,&n) && n)
        {
            for(id = 0 ,i = 1 ;i <= n ;i ++)
            {
                scanf("%lf %lf %lf %lf" ,&x1 ,&y1 ,&x2 ,&y2);
                E[++id].l = x1;
                E[id].r = x2 ,E[id].h = y1 ,E[id].mk = 1;
                tmp[id] = x1;
    
                E[++id].l = x1;
                E[id].r = x2 ,E[id].h = y2 ,E[id].mk = -1;
                tmp[id] = x2;
            }
            sort(E + 1 ,E + id + 1 ,camp);
            sort(tmp + 1 ,tmp + id + 1);
    
            int n2 = n * 2;
            for(id = 0 ,i = 1 ;i <= n2 ;i ++)
            {
                if(i == 1 || tmp[i] != tmp[i-1])
                num[++id] = tmp[i];
            }
            BuidTree();
            E[0].h = E[1].h;
            Ans = 0;
            for(i = 1 ;i <= n2 ;i ++)
            {
                Ans += len[1] * (E[i].h - E[i-1].h);
                int l = search2(E[i].l ,id);
                int r = search2(E[i].r ,id);
                Update(1 ,id ,1 ,l ,r ,E[i].mk);
            }
            printf("Test case #%d
    " ,cas ++);
            printf("Total explored area: %.2lf
    
    " ,Ans);
        }
        return 0;
    
    }
    



  • 相关阅读:
    网络芯片应用:GPS公交车行驶记录仪
    “黑暗潜伏者” -- 手机病毒新型攻击方式
    Android导入工程提示Invalid project description
    设计模式_代理模式
    el简略说明与11个隐含对象
    jsp九大内置对象
    js全局函数
    python基础:multiprocessing的使用
    pgAdmin III 使用图解
    windows下简单安装postgres
  • 原文地址:https://www.cnblogs.com/csnd/p/12062425.html
Copyright © 2011-2022 走看看