题目链接:点击查看

题目大意:给出n个矩形的左下角坐标和右上角坐标,求出其总面积,注意,矩形会重叠,重叠部分只计算一次

题目分析:如果暴力做需要考虑容斥原理,两两矩形组合判断是否重合,十分麻烦而且时间复杂度也十分的高,这里用到了线段树和扫描线的思想,我通过这篇博客学习的,感觉写的不错:点击查看

然后我用自己的风格写了一下这个题,具体需要注意的我都写在注释里了,直接上代码吧:

对了,需要注意的是,对于扫描线这种题目,如果数据不为整数或数据量过大,我们需要对线段树的区间进行离散化处理

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<sstream>
#include<cmath>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=210;struct Node
{int l,r,cover;double right,left;double len;
}tree[N<<2];vector<double>v;struct node
{double x,upy,downy;int into;node(){x=upy=downy=0;into=0;}
}line[N];bool cmp(node a,node b)
{return a.x<b.x;
}void build(int k,int l,int r)
{tree[k].l=l;tree[k].r=r;tree[k].cover=0;tree[k].len=0;tree[k].left=v[l-1];tree[k].right=v[r-1];if(l+1==r)return;int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid,r);//注意这里是mid到r,举个例子,如果端点有四个,分别是10,20,30,40,我们希望的区间是[10,20],[20,30],[30,40]而不是[10,20]和[30,40]
}void pushup(int k)
{if(tree[k].cover>0)//如果被覆盖了,长度更新为两个端点之差 tree[k].len=tree[k].right-tree[k].left;else if(tree[k].l+1==tree[k].r)//如果没被覆盖,并且是“叶节点”,长度更新为0 tree[k].len=0;else//如果没被覆盖,但不是叶子节点,长度更新为左儿子和右儿子之和 tree[k].len=tree[k<<1].len+tree[k<<1|1].len;
}void update(int k,int l,int r,int val)
{if(tree[k].l>r||tree[k].r<l)return;if(tree[k].l>=l&&tree[k].r<=r){tree[k].cover+=val;pushup(k);return;}update(k<<1,l,r,val);update(k<<1|1,l,r,val);pushup(k);
}int main()
{
//  freopen("input.txt","r",stdin);int n;int kase=0;while(scanf("%d",&n)!=EOF&&n){v.clear();for(int i=1;i<=n;i++){double x1,y1,x2,y2;scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);v.push_back(y1);v.push_back(y2);line[i].downy=line[i+n].downy=y1;line[i].upy=line[i+n].upy=y2;line[i].x=x1;line[i+n].x=x2;line[i].into=1;line[i+n].into=-1;}sort(v.begin(),v.end());//离散化--排序 sort(line+1,line+1+2*n,cmp);//对x坐标排序 v.erase(unique(v.begin(),v.end()),v.end());//离散化--去重 int len=v.size();//得到离散化后的y坐标的长度 double ans=0;build(1,1,len);//建树需要建len个点,相邻的每两个点所组成了len-1个区间 for(int i=1;i<=2*n;i++)//遍历2*n个x点 {ans+=tree[1].len*(line[i].x-line[i-1].x);//每次结果相加 int l=lower_bound(v.begin(),v.end(),line[i].downy)-v.begin()+1;//求出离散化后下面的y的编号 int r=lower_bound(v.begin(),v.end(),line[i].upy)-v.begin()+1;//求出离散化后上面的y的编号 update(1,l,r,line[i].into);//更新区间覆盖情况 }printf("Test case #%d\nTotal explored area: %.2f\n\n",++kase,ans);}return 0;
}

HDU - 1542 Atlantis(线段树+扫描线)相关推荐

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

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

  2. HDU 1542 Atlantis 线段树+离散化+扫描线

    题意:给出一些矩形的最上角坐标和右下角坐标,求这些矩形的面积并. NotOnlySuccess 线段树专辑中扫描线模板题,弱智的我对着大大的代码看了一下午才搞懂. 具体见思路见注释=.= #inclu ...

  3. POJ 1151 Atlantis 线段树+扫描线

    解题思路: 先将y轴进行离散化.n个矩形的2n个横边纵坐标共构成最多2n-1个区间的边界,对这些区间编号,建立起线段树. x轴记录左边和右边,左边时是矩形面积增加,覆盖层数增加边,右边是形面积减少,覆 ...

  4. HDU 1828 Picture 线段树 扫描线

    写完后才发现数据是int不是double... //#pragma comment(linker, "/STACK:1024000000,1024000000") #include ...

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

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

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

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

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

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

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

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

  9. HDU 2795 Billboard (线段树+贪心)

    HDU 2795 Billboard (线段树+贪心) 手动博客搬家:本文发表于20170822 21:30:17, 原地址https://blog.csdn.net/suncongbo/articl ...

最新文章

  1. date javascript 时区_js Date 时间戳 时区等问题总结
  2. 前谷歌高管给初入职场新人的14条忠告
  3. Spring boot容器导入组件
  4. django连接redis(文章看着不错)
  5. es文件浏览器怎么用_ES文件浏览器VIP直装版
  6. 【论文笔记】NLP 预训练模型综述
  7. 如何为自定义的控件在工具箱中自定义个性化的图标
  8. Kotlin解析JSON数据
  9. arduino人体红外传感器_Arduino 使用人体红外感应模块 HC-SR501
  10. 坑爹的工行Chrome网银插件
  11. opencv最小外接矩形
  12. storm tread 耐克_耐克 Nike Air Zoom Pegasus 35 Shield 登月35代跑鞋
  13. 所有键都无法进入bios(按任何键都进不去bios)
  14. 我国网络营销发展的现状、障碍与对策
  15. 一师一优课计算机课程,教育部一师一优课在线会客室在南京成功直播
  16. 大数据——Flume组件Source、Channel和Sink具体使用
  17. 设置漂亮的eclipse主题(Theme)风格
  18. java qq托盘 消息提醒_如何仿QQ实现托盘闪动消息提醒
  19. python爬取qq空间说说
  20. java 工资管理系统_Java工资管理系统

热门文章

  1. 分布式事务六种解决方案
  2. 深入探讨Container
  3. 使用Zookeeper实现leader选举-LeaderSelector
  4. Curator实现分布式锁的基本原理-InterProcessMutex.acquire
  5. MyBatis 架构分层与模块划分-核心处理层
  6. Spring-Cloud中的 熔断、限流、降级
  7. 分布式架构的NoSQL
  8. Request_请求转发
  9. SpringBoot高级-缓存-RedisTemplate序列化机制
  10. linux相关函数,linux学习-信号相关函数