• poj1151(Atlantis)& hdu1542 (Atlantis)(线段树+扫描线)


    题目地址:poj1151(Atlantis)hdu1542 (Atlantis)

    题目大意:

         给你N个矩形,求出矩形在平面图构成的面积。

    解题思路:

         线段数+扫描线。

    需要注意:

         记住线段树返回的cnt 是从左往右每条扫描线 投影Y轴的长度,就能很好的理解线段数+扫描线的代码。

    推荐博客:线段树辅助——扫描线法计算矩形面积并,这个博客说的是从下到上扫描,离散化x坐标,原理是一样的,我的代码是从左往右扫描,离散化Y坐标以Y坐标建树。

    代码:

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <cstdio>
      7 #include <string>
      8 #include <bitset>
      9 #include <vector>
     10 #include <queue>
     11 #include <stack>
     12 #include <cmath>
     13 #include <list>
     14 #include <map>
     15 #include <set>
     16 using namespace std;
     17 /***************************************/
     18 #define ll long long
     19 #define int64 __int64
     20 /***************************************/
     21 const int INF = 0x7f7f7f7f;
     22 const double eps = 1e-8;
     23 const double PIE=acos(-1.0);
     24 const int d1x[]= {0,-1,0,1};
     25 const int d1y[]= {-1,0,1,0};
     26 const int d2x[]= {0,-1,0,1};
     27 const int d2y[]= {1,0,-1,0};
     28 const int fx[]= {-1,-1,-1,0,0,1,1,1};
     29 const int fy[]= {-1,0,1,-1,1,-1,0,1};
     30 /***************************************/
     31 void openfile()
     32 {
     33     freopen("data.in","rb",stdin);
     34     freopen("data.out","wb",stdout);
     35 }
     36 /**********************华丽丽的分割线,以上为模板部分*****************/
     37 const int M=300;
     38 
     39 struct tree
     40 {
     41     int left,right;  //左右区间
     42     double turel,turer,cnt; //记录左右区间的真实值和 投影Y轴坐标的覆盖的程度cnt
     43     int c;  //记录该区间被覆盖几次。
     44 
     45 } node[M*4];
     46 struct Line
     47 {
     48     double x,y1,y2;    //记录每一条扫描线
     49     int f;  //标记入边1,出边为-1
     50 }line[M];  //储存所有的线段
     51 int cnt;
     52 double y[M];  //将y的坐标记录然后离散化
     53 bool cmp(Line a,Line b)  //排序 
     54 {
     55     return a.x<b.x;
     56 } 
     57 void build__tree(int id,int l,int r)  //初始化树
     58 {
     59     int mid=(l+r)/2;
     60     node[id].turel=y[l];
     61     node[id].turer=y[r];
     62     node[id].left=l;
     63     node[id].right=r;
     64     node[id].cnt=0;
     65     node[id].c=0;
     66     if (l+1==r)
     67         return ;
     68     build__tree(id*2,l,mid);
     69     build__tree(id*2+1,mid,r);
     70 }
     71 void upcnt(int id)   //更新投影Y轴的线段
     72 {
     73     if (node[id].c>0)
     74     {
     75         node[id].cnt=node[id].turer-node[id].turel;
     76         return ;
     77     }
     78     if (node[id].left+1==node[id].right)
     79         node[id].cnt=0;
     80     else
     81         node[id].cnt=node[id*2].cnt+node[id*2+1].cnt;
     82 }
     83 void updata(int id,Line v)
     84 {
     85     if (node[id].turel==v.y1&&node[id].turer==v.y2)
     86     {
     87         node[id].c+=v.f;
     88         upcnt(id);
     89         return ;
     90     }
     91     if (v.y2<=node[id*2].turer)
     92         updata(id*2,v);
     93     else if (v.y1>=node[id*2+1].turel)
     94         updata(id*2+1,v);
     95     else
     96     {
     97         Line tmp;
     98         tmp=v;
     99         tmp.y2=node[id*2].turer;
    100         updata(id*2,tmp);
    101         tmp=v;
    102         tmp.y1=node[id*2+1].turel;
    103         updata(id*2+1,tmp);
    104     }
    105     upcnt(id);
    106 }
    107 
    108 int main()
    109 {
    110     int n;
    111     int icas=0;
    112     while(scanf("%d",&n)&&n)
    113     {
    114         int i,j;
    115         int d=1;
    116         for(i=1;i<=n;i++)
    117         {
    118             double x1,x2,y1,y2;
    119             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
    120             line[d].x=x1;
    121             line[d].y1=y1;
    122             line[d].y2=y2;
    123             line[d].f=1;
    124             y[d]=y1;
    125             d++;
    126             line[d].x=x2;
    127             line[d].y1=y1;
    128             line[d].y2=y2;
    129             line[d].f=-1;
    130             y[d]=y2;
    131             d++;
    132         }
    133         sort(y+1,y+d);
    134         sort(line+1,line+d,cmp);
    135         build__tree(1,1,d-1);
    136         updata(1,line[1]);
    137         double sum=0;
    138         for(i=2;i<d;i++)
    139         {
    140             sum+=node[1].cnt*(line[i].x-line[i-1].x);
    141             updata(1,line[i]);
    142         }
    143         printf("Test case #%d
    ",++icas);
    144         printf("Total explored area: %.2lf
    
    ",sum);
    145     }
    146     return 0;
    147 }
    View Code
  • 相关阅读:
    C语言 · 新生舞会
    C语言 · 集合运算
    C语言 · 字符串的展开
    C语言 · 学做菜
    C语言 · 最长公共子序列 · 最长字符序列
    C语言 · 复数求和
    C语言 · 扶老奶奶过街
    C语言 · 删除重复元素
    1-3
    1-4
  • 原文地址:https://www.cnblogs.com/ZhaoPengkinghold/p/4093487.html
Copyright © 2020-2023  润新知