zoukankan      html  css  js  c++  java
  • POJ 1151 Atlantis 线段树+扫描线

    解题思路:

    先将y轴进行离散化。n个矩形的2n个横边纵坐标共构成最多2n-1个区间的边界,对这些区间编号,建立起线段树。

    x轴记录左边和右边,左边时是矩形面积增加,覆盖层数增加边,右边是形面积减少,覆盖层数减少边。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 using namespace std;
      5 double y[210];
      6 int ncount;
      7 struct line
      8 {
      9     double x,y1,y2;
     10     bool left;
     11 };
     12 line lines[210];
     13 struct node
     14 {
     15     int l,r;
     16     node *pl,*pr;
     17     double len;
     18     int c;
     19 };
     20 bool cmp(const line &a,const line &b)
     21 {
     22     return a.x<b.x;
     23 }
     24 node t[1010];
     25 void build(node *root,int l,int r)
     26 {
     27     root->l=l;
     28     root->r=r;
     29     root->c=0;
     30     root->len=0;
     31     if(l==r) return;
     32     ncount++;
     33     root->pl=t+ncount;
     34     ncount++;
     35     root->pr=t+ncount;
     36     build(root->pl,l,(l+r)/2);
     37     build(root->pr,(l+r)/2+1,r);
     38 }
     39 int searchy(int e,double x)
     40 {
     41     int s=0;
     42     e=e-1;
     43     while(s<=e)
     44     {
     45         int mid=s+(e-s)/2;
     46         if(y[mid]==x)
     47             return mid;
     48         else if(y[mid]>x)
     49             e=mid-1;
     50         else s=mid+1;
     51     }
     52     return -1;
     53 }
     54 int mid(node *p)
     55 {
     56     return (p->l+p->r)/2;
     57 }
     58 void Insert(node *root,int l,int r)
     59 {
     60     if(root->l==l&&root->r==r)
     61     {
     62         root->len=y[r+1]-y[l];
     63         root->c++;
     64         return ;
     65     }
     66     if(r<=mid(root))
     67         Insert(root->pl,l,r);
     68     else if(l>=mid(root)+1)
     69         Insert(root->pr,l,r);
     70     else
     71     {
     72         Insert(root->pl,l,mid(root));
     73         Insert(root->pr,mid(root)+1,r);
     74     }
     75     if(root->c==0)
     76         root->len=root->pl->len+root->pr->len;
     77 }
     78 void Delete(node *root,int l,int r)
     79 {
     80     if(root->l==l&&root->r==r)
     81     {
     82         root->c--;
     83         if(root->c==0)
     84         {
     85             if(root->l==root->r)
     86                 root->len=0;
     87             else
     88                 root->len=root->pl->len+root->pr->len;
     89         }
     90         return;
     91     }
     92     if(r<=mid(root))
     93         Delete(root->pl,l,r);
     94     else if(l>=mid(root)+1)
     95         Delete(root->pr,l,r);
     96     else
     97     {
     98         Delete(root->pl,l,mid(root));
     99         Delete(root->pr,mid(root)+1,r);
    100     }
    101     if(root->c==0)
    102         root->len=root->pl->len+root->pr->len;
    103 }
    104 int main()
    105 {
    106     int n;
    107     double x1,x2,y1,y2;
    108     int yc,lc;
    109     int ca=0;
    110     while(~scanf("%d",&n)&&n)
    111     {
    112         ca++;
    113         lc=yc=0;
    114         for(int i=0; i<n; i++)
    115         {
    116             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
    117             y[yc++]=y1;
    118             y[yc++]=y2;
    119             lines[lc].x=x1;
    120             lines[lc].y1=y1;
    121             lines[lc].y2=y2;
    122             lines[lc].left=1;
    123             lc++;
    124 
    125             lines[lc].x=x2;
    126             lines[lc].y1=y1;
    127             lines[lc].y2=y2;
    128             lines[lc].left=0;
    129             lc++;
    130         }
    131         sort(y,y+yc);
    132         yc=unique(y,y+yc)-y;
    133         build(t,0,yc-2);
    134         sort(lines,lines+lc,cmp);
    135         double ans=0;
    136         for(int i=0; i<lc-1; i++)
    137         {
    138             int l=searchy(yc,lines[i].y1);
    139             int r=searchy(yc,lines[i].y2)-1;
    140             if(lines[i].left)
    141                 Insert(t,l,r);
    142             else
    143                 Delete(t,l,r);
    144             ans+=t[0].len*(lines[i+1].x-lines[i].x);
    145         }
    146         printf("Test case #%d
    ",ca);
    147         printf("Total explored area: %.2f
    
    ",ans);
    148     }
    149 }
  • 相关阅读:
    【2018年11月21日】煤炭行业的估值高度排名
    【2018年11月16日】绩优超跌个股排名
    【2018年11月15日】航空航天与国防行业的估值高度排名
    【2018-11-15】中证1000指数的估值详情
    【11-13】A股主要指数的市盈率(PE)估值高度
    【2018年11月12日】其他化学制品行业的股票估值
    【2018-11-09】中证500指数的估值详情
    【2018年10月29日】食品、饮料与烟草行业的估值高度排名
    2018-10-29 A股主要指数的市盈率(PE)估值高度
    中证500等主要指数的市盈率(PE)估值高度
  • 原文地址:https://www.cnblogs.com/kearon/p/6925546.html
Copyright © 2011-2022 走看看