解题思路:

先将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\n",ca);
147         printf("Total explored area: %.2f\n\n",ans);
148     }
149 }

转载于:https://www.cnblogs.com/kearon/p/6925546.html

POJ 1151 Atlantis 线段树+扫描线相关推荐

  1. hdu 1542 Atlantis (线段树+扫描线)

    http://acm.hdu.edu.cn/showproblem.php?pid=1542 单纯的线段树+扫描线求面积并,需要离散化. code: #include <cstdlib> ...

  2. HDU - 1542 Atlantis(线段树+扫描线)

    题目链接:点击查看 题目大意:给出n个矩形的左下角坐标和右上角坐标,求出其总面积,注意,矩形会重叠,重叠部分只计算一次 题目分析:如果暴力做需要考虑容斥原理,两两矩形组合判断是否重合,十分麻烦而且时间 ...

  3. poj 1151(线段树求面积并)

    解题思路:线段树求面积并,水题 #include<iostream> #include<cstdio> #include<cstring> #include< ...

  4. poj 1151 Atlantis

    类型:离散化 题目:http://poj.org/problem?id=1151 来源:Mid-Central European Regional Contest 2000 思路[一]: (1)使用m ...

  5. 线段树扫描线求矩形周长详解

    线段树扫描线求矩形周长详解 原创 wucstdio 最后发布于2018-04-24 16:12:09 阅读数 841 收藏 发布于2018-04-24 16:12:09 版权声明:本文为博主原创文章, ...

  6. hdu3255 线段树扫描线求体积

    题意:       给你n个矩形,每个矩形上都有一个权值(该矩形单位面积的价值),矩形之间可能重叠,重叠部分的权值按照最大的算,最后问这n个矩形组成的图形的最大价值. 思路:       线段树扫描线 ...

  7. hdu1542 线段树扫描线求矩形面积的并

    题意:       给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路:       自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...

  8. POJ 2352 Stars (线段树)

    POJ 2352 Stars (线段树) 手动博客搬家:本文发表于20170819 22:11:49, 原地址https://blog.csdn.net/suncongbo/article/detai ...

  9. HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

    版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...

最新文章

  1. windows开启ssh当跳板机
  2. 诺奖10年,干细胞领域再突破!华大单细胞技术助力获得人类体外诱导全能干细胞...
  3. 运维数据库平台~inception审核规则详解
  4. hdu 1867 求两个串的和最小 ,KMP
  5. 最新技术资讯,你必须知道的Python 3.9新功能
  6. gbdt子采样参数的理解
  7. Help View修复
  8. 面试中有这些特征的公司可以pass了
  9. BEGINNING SHAREPOINT#174; 2013 DEVELOPMENT 第1章节--SharePoint 2013 介绍 SharePoint 2013 平台...
  10. BGP 基本配置参考
  11. 用python孵一颗彩蛋,今日份来自程序员的浪漫
  12. 过年啦!什么是你的春节专属年味儿?
  13. 特殊符号大全复制_上榜!4.15特殊符号大全优美的制作网名符号案例分享,适合微信游戏昵称...
  14. 大学生微信小程序项目总结
  15. 伙伴们,小毛祝你们新的一年神马都给力!!!
  16. cad渐开线齿轮轮廓绘制_CAD渐开线齿形怎么绘制
  17. yuque-helper 1.0 发布了
  18. 微分中的d是什么意思。
  19. 别把激励员工变成收买员工
  20. 爱智会平台荣膺2018全球物联网大会最佳数字会务服务伙伴奖

热门文章

  1. PAT_B_1053_Java(20分)
  2. pcl程序如何在linux上运行,Ubuntu系统安装PCL 1.9及以上版本
  3. ACM成长之路(干货) 我爱ACM,与君共勉
  4. uC/OS-II源码分析(总体思路 二)
  5. OpenCV中的HOG+SVM在自动驾驶车辆检测中的应用实例
  6. MySQL 中 AUTO_INCREMENT 的“坑” --重复值问题
  7. 感知算法论文(十):Towards Universal Object Detection by Domain Attention(2019)
  8. 【Android 修炼手册系列内容】
  9. 整型变量(int)与字节数组(byte[])的相互转换
  10. 编码gbk的不可映射字符_Python基础:编码表和字符的故事