P - Atlantis (线段树+扫描线)
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 (线段树+扫描线)的更多相关文章
- hdu1542 Atlantis 线段树--扫描线求面积并
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...
- HDU 1542 - Atlantis - [线段树+扫描线]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...
- POJ 1151 - Atlantis 线段树+扫描线..
离散化: 将所有的x轴坐标存在一个数组里..排序.当进入一条线段时..通过二分的方式确定其左右点对应的离散值... 扫描线..可以看成一根平行于x轴的直线..至y=0开始往上扫..直到扫出最后一条平行 ...
- POJ1151 Atlantis 线段树扫描线
扫描线终于看懂了...咕咕了快三个月$qwq$ 对于所有的横线按纵坐标排序,矩阵靠下的线权值设为$1$,靠上的线权值设为$-1$,然后执行线段树区间加减,每次的贡献就是有效宽度乘上两次计算时的纵坐标之 ...
- POJ 1151:Atlantis 线段树+扫描线
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19374 Accepted: 7358 Descrip ...
- hdu 1542 Atlantis (线段树扫描线)
大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- hdu 1542 Atlantis(线段树,扫描线)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
随机推荐
- nodejs(7)练习 http 和 express 创建简单的服务器
http const http = require('http') // 创建服务器 const server = http.createServer() // 绑定事件,监听客户端的请求 serve ...
- 数的划分(DFS、DP)
https://www.luogu.com.cn/problem/P1025 题目描述 将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序). 例如:n=7,k=3,下面三种分法被认为是 ...
- 题解 P1082 【同余方程】
题目 这里给出非递归的 exgcd 做法 [基础] ( 只需要非递归的同学麻烦跳过 ) 由于欧几里德算法 ( 又名辗转相除法 ) 可以帮助我们求出最大公约数,并且提出对于 \(\forall a,b\ ...
- TensorFlow(一)
一.Hello World 1.只安装CPU版,TensorFlow1.14.0版本代码 # import tensorflow as tf import tensorflow.compat.v1 a ...
- Linux安装maven超级详细步骤
一 服务器联网情况下安装maven 1.安装wget命令 如果需要通过使用wget命令,直接通过网络下载maven安装包时,需要在linux系统中安装wget命令. yum -y install wg ...
- ubuntu下git的使用
1.安装git sudo apt-get install git sudo apt-get install git-core 2.配置git lzb@lzb:~$ git config --globa ...
- UVA 10273
我是用暴力过的,虽然网上说刘汝佳出的这道题考的是堆,我不太懂,..用暴力时间复杂度高一些,但是一样能过 所要注意的就是周期问题,因为只要同时存在某一天超过一头牛产奶量最小,就不会杀牛,而每头牛的周期和 ...
- IOC 本质是为了实现 AOP|火影鸣人
@JFinal 波总在 JFinal 4.8 发布新闻的评论 中给出了下面的表述: IOC 本质是为了实现 AOP 我有点吃惊, 没想到 Java 界的大佬对这两个概念有和我完全不一致的认识. 所以写 ...
- POJ-1015 Jury Compromise(dp|01背包)
题目: In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting ...
- nginx中server块的匹配顺序
客户端发出一个http请求时,nginx收到后会取出header头中的host,与nginx.conf中每个server的server_name进行匹配,以此决定到底由哪一个server块来处理这个请 ...