There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity. 

InputThe input file consists of several test cases. Each test case starts with a line containing a single integer n (1<=n<=100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0<=x1<x2<=100000;0<=y1<y2<=100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.

The input file is terminated by a line containing a single 0. Don’t process it.OutputFor each test case, your program should output one section. The first line of each section must be “Test case #k”, where k is the number of the test case (starting with 1). The second one must be “Total explored area: a”, where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.

Output a blank line after each test case. 
Sample Input

2
10 10 20 20
15 15 25 25.5
0

Sample Output

Test case #1
Total explored area: 180.00
题解:扫描线常规操作,如果不会先看大神的讲解再来:https://blog.csdn.net/xianpingping/article/details/83032798
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
double x[maxn];
struct node
{
double l,r,h;
int d;
bool operator < (const node &a)const//按纵坐标从小到大排序
{
return h<a.h;
}
}line[maxn];
int cnt[maxn<<];//cnt[rt]表示该节点的覆盖次数,只要不为0就是被覆盖过
double sum[maxn<<];//线段树sum[rt]中每一个节点都是一个区间,sum[rt]表示该节点区间中的总有效覆盖长度
double area;
void pushup(int l,int r,int rt)
{
if(cnt[rt])//如果该节点(就是一个区间)全部被覆盖,那么sum就是这个区间的长度了~
sum[rt]=x[r+]-x[l];//x的下标是点,对于线段树的一个区间要进行右边下标+1再减去左边
else //否则要进行左右儿子的加和,因为不连续啊~
sum[rt]=sum[rt*]+sum[rt*+];
}
void update(int L,int R,int v,int l,int r,int rt)//在L,R区间覆盖次数加上v,即如果v为1就加1,为-1就减1
{
if(L<=l&&R>=r)
{
cnt[rt]+=v;
pushup(l,r,rt);//改变了cnt数组后要重新pushup
return ;
}
int mid=(l+r)/;//下面常规操作~
if(L<=mid)
update(L,R,v,l,mid,rt*);
if(R>=mid+)
update(L,R,v,mid+,r,rt*+);
pushup(l,r,rt);
}
int main()
{
int t,k=;
while(cin>>t&&t)
{
memset(cnt,,sizeof(cnt));//初始化全部为0
memset(sum,,sizeof(sum));
area=; //求得面积
int n=,m=;//x数组得最大元素个数,line数组得最大元素个数
for(int i=;i<=t;i++)//记录信息
{
double x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
x[++n]=x1;
x[++n]=x2;
line[++m]=(node){x1,x2,y1,};
line[++m]=(node){x1,x2,y2,-};
}
sort(x+,x++n);//对x数组从小打大排序
sort(line+,line++m);//对line扫描线数组按高度(即y)从小到大排序
int r=unique(x+,x++n)-x-;//r个不同的x将一条线段分成r-1个小区间,这也是后面查询总区长度是1到r-1和R--的原因
for(int i=;i<m;i++)//这里是对扫描线进行扫描~,扫描m-1次即可
{
int L=lower_bound(x+,x+r+,line[i].l)-x;
int R=lower_bound(x+,x+r+,line[i].r)-x;
R--;//每一个节点是一个区间,这里是将点转化为区间的操作
update(L,R,line[i].d,,r-,);
area+=sum[]*(line[i+].h-line[i].h);//用总有效长度乘上两条扫描线之间的距离即得到该块面积
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",k++,area);
}
return ;
}

												

P - Atlantis (线段树+扫描线)的更多相关文章

  1. hdu1542 Atlantis 线段树--扫描线求面积并

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

  2. HDU 1542 - Atlantis - [线段树+扫描线]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  3. HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  4. 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...

  5. POJ 1151 - Atlantis 线段树+扫描线..

    离散化: 将所有的x轴坐标存在一个数组里..排序.当进入一条线段时..通过二分的方式确定其左右点对应的离散值... 扫描线..可以看成一根平行于x轴的直线..至y=0开始往上扫..直到扫出最后一条平行 ...

  6. POJ1151 Atlantis 线段树扫描线

    扫描线终于看懂了...咕咕了快三个月$qwq$ 对于所有的横线按纵坐标排序,矩阵靠下的线权值设为$1$,靠上的线权值设为$-1$,然后执行线段树区间加减,每次的贡献就是有效宽度乘上两次计算时的纵坐标之 ...

  7. POJ 1151:Atlantis 线段树+扫描线

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19374   Accepted: 7358 Descrip ...

  8. hdu 1542 Atlantis (线段树扫描线)

    大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...

  9. hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  10. hdu 1542 Atlantis(线段树,扫描线)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

随机推荐

  1. Django学习笔记〇四——数据库ORM的使用(有待修改)

    Django框架基本上都是要和数据库结合使用的,我在以前讲过SQLAlchemy框架的使用,Django支持的不是SQLAlchemy,但是也内嵌了ORM框架,可以不需要直接面对数据库编程,而可以通过 ...

  2. 在h5页面上添加音乐播放

    接到需求说要做一个h5轮播图,同时配上背景音乐. Html部分: <!--音乐开始--> <div id="music"> <div id=" ...

  3. CodeForces - 748C Santa Claus and Robot

    题意:机器人在网格线上行走,从p1点开始,沿最短路径到p2,再沿最短路径到p3,依此类推.在此过程中留下了行走的运动轨迹,由“RLDU”表示.问若只给出运动轨迹,求最少的pi点的个数. 分析:pi到p ...

  4. BZOJ [Scoi2010]游戏

    题解: 解法一:建立图论模型,发现只要联通块中有环则这个联通块中的值都可以被攻击到 如果是树,则只能攻击size-1个 解法二:二分图匹配,二分答案,看看是否能攻击到mid #include<i ...

  5. JDBC,ResultSet对像多次使用后再关闭的问题

    原文链接:https://yq.aliyun.com/wenzhang/show_111763 问题描述 //代码... ResultSet rs = this.conn.prepareStateme ...

  6. 吴裕雄--天生自然TensorFlow2教程:Broadcasting

    Broadcasting可以理解成把维度分成大维度和小维度,小维度较为具体,大维度更加抽象.也就是小维度针对某个示例,然后让这个示例通用语大维度. import tensorflow as tf x ...

  7. 正文内容 python3编码问题

    来源:http://www.jb51.net/article/92006.htm 以下是全文: 这两天写了个监测网页的爬虫,作用是跟踪一个网页的变化,但运行了一晚出现了一个问题....希望大家不吝赐教 ...

  8. IO流处理文件读取到字节数组,再从字节数组读取到文件,Java实现

    package cn.zhang.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; impo ...

  9. 20个GitHub最热门的Java开源项目:文档、框架、工具

    专注于Java领域优质技术,欢迎关注 文章来源:JavaGuide 以下涉及到的数据统计,数据来源:https://github.com/trending/java?since=monthly[1] ...

  10. Spring Cloud Alibaba 教程 | Nacos(四)

    Nacos环境隔离 Nacos管理台有一个单独的菜单"命名空间",里面默认存在一个名为"public"的默认命名空间,我们在使用Nacos时不管是作为注册中心还 ...