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. JSON整理

    1.什么是JSON JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式. 2.JSON基于两种结构: (1 )“名称/值“对的集合(A co ...

  2. POJ 1013:Counterfeit Dollar

    Counterfeit Dollar Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42028   Accepted: 13 ...

  3. js数组全等

    js 数组全等(对象) if(this.eqOrNotEq(arr)){} eqOrNotEq(arr) { return !arr.some(function(value, index) { ret ...

  4. 使用maven打包问题

    项目打包:选择项目 右键->run as-> maven install . 项目中使用的是maven项目,将项目打包成war的时候有时候会出现 出现这种情况的时候解决步骤如下: 选择要打 ...

  5. cmd 进入指定文件夹

    1.通常情况下,我们要进入其他盘符下的任意目录,需要在CMD窗口运行两次命令:第一次,进入盘符,第二次进入指定目录 #进入D盘 d: #进入D盘下的anaconda目录 cd anacond 2.通过 ...

  6. C/C++源程序到可执行程序的过程

    源程序.cpp  预处理得到 预处理文件.i   编译得到 汇编文件.S    汇编得到 目标文件.o     链接得到 可执行文件 例子:main.cpp  fun.cpp fun.h #inclu ...

  7. Res-net 标准版本源码差异-官方源码示例

    # resnet https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v1.py https://gi ...

  8. 运行roscore出现unable to contact my own server无法启动小海龟的部分故障问题解决

    运行roscore后,出现下图这种情况(unable to contact my own server) 原因是找不到http://后面那些,ping不到域名或IP. 参考http://www.ros ...

  9. JavaScript数组打平(4种方法)

    let arr = [1, 2, [3, 4, 5, [6, 7, 8], 9], 10, [11, 12]]; flatten1 = arr => arr.flat(Infinity) fla ...

  10. java使用HSSFWorkbook下载Excel表格

    @RequestMapping(value = "/exportVectorExcelN", method = RequestMethod.GET) @ResponseBody @ ...