zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    POJ 3660 Cow Contest (floyd求联通关系)
    POJ 3660 Cow Contest (最短路dijkstra)
    POJ 1860 Currency Exchange (bellman-ford判负环)
    POJ 3268 Silver Cow Party (最短路dijkstra)
    POJ 1679 The Unique MST (最小生成树)
    POJ 3026 Borg Maze (最小生成树)
    HDU 4891 The Great Pan (模拟)
    HDU 4950 Monster (水题)
    URAL 2040 Palindromes and Super Abilities 2 (回文自动机)
    URAL 2037 Richness of binary words (回文子串,找规律)
  • 原文地址:https://www.cnblogs.com/ZhaoPengkinghold/p/4093487.html
Copyright © 2011-2022 走看看