【POJ1151】Atlantis
题目大意:给定 N 个矩形,求这些矩形的面积并。
题解:采用扫描线算法。
首先,按照矩形的横坐标排序,在纵坐标方向上维护一根扫描线被覆盖的长度,在这里采用线段树维护。统计答案时,从左到右扫描 2N 个 X 坐标,两个坐标之间的扫描线被覆盖的长度相等,因此直接长乘宽计入答案即可。
注意事项
- 由于坐标不是整数,因此采用离散化。
- 线段树动态开点即可。
- 跟以往线段树不同的地方在于,这里的线段树的区间修改并没有没有下传标记。原因可以总结为查询时只询问根节点的信息,没有必要下传标记。
代码如下
#include <cstdio>
#include <iostream>
#include <memory>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=210;
int n,kase;
struct re{
double x,y,y1;
int is;
}rec[maxn];
bool cmp(const re &a,const re &b){return a.x<b.x;}
double d[maxn];int cnt;
inline int query(double x){return lower_bound(d+1,d+cnt+1,x)-d;}
struct node{
#define ls(x) t[x].lc
#define rs(x) t[x].rc
int lc,rc,tag;
double len;
}t[maxn<<1];
int tot,root;
inline void maintain(int o,int l,int r){
if(t[o].tag>0)t[o].len=d[r+1]-d[l];
else t[o].len=t[ls(o)].len+t[rs(o)].len;
}
void modify(int &o,int l,int r,int x,int y,int val){
if(!o)o=++tot;
if(l==x&&r==y){t[o].tag+=val;maintain(o,l,r);return;}
int mid=l+r>>1;
if(y<=mid)modify(ls(o),l,mid,x,y,val);
else if(x>mid)modify(rs(o),mid+1,r,x,y,val);
else modify(ls(o),l,mid,x,mid,val),modify(rs(o),mid+1,r,mid+1,y,val);
maintain(o,l,r);
}
void read_and_parse(){
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",&rec[i].x,&rec[i].y,&rec[i+n].x,&rec[i+n].y);
rec[i].y1=rec[i+n].y,rec[i+n].y1=rec[i].y;
rec[i].is=0,rec[i+n].is=1;
d[i]=rec[i].y,d[i+n]=rec[i+n].y;
}
sort(rec+1,rec+2*n+1,cmp);
sort(d+1,d+2*n+1);
cnt=unique(d+1,d+2*n+1)-d-1;
}
void solve(){
double ans=0;
for(int i=1;i<2*n;i++){
int l=query(rec[i].y),r=query(rec[i].y1);
if(!rec[i].is)modify(root,1,cnt-1,l,r-1,1);
else modify(root,1,cnt-1,r,l-1,-1);
ans+=(rec[i+1].x-rec[i].x)*t[root].len;
}
printf("Test case #%d\n",++kase);
printf("Total explored area: %.2lf\n",ans);
puts("");
}
int main(){
while(scanf("%d",&n)&&n){
memset(t,0,sizeof(t)),memset(rec,0,sizeof(rec));
tot=root=0;
read_and_parse();
solve();
}
return 0;
}
【POJ1151】Atlantis的更多相关文章
- 【POJ1151】Atlantis(线段树,扫描线)
[POJ1151]Atlantis(线段树,扫描线) 题面 Vjudge 题解 学一学扫描线 其实很简单啦 这道题目要求的就是若干矩形的面积和 把扫描线平行于某个轴扫过去(我选的平行\(y\)轴扫) ...
- 【POJ1151】【扫描线+线段树】Atlantis
Description There are several ancient Greek texts that contain descriptions of the fabled island Atl ...
- 【HDU1542】Atlantis
题意 给出n个矩形的左下角和右上角的坐标,计算总的面积(相交部分只算一次). 分析 线段树扫描线的模板题. 将每个矩形都拆成上下两条线段,然后从下网上扫,当遇到底边时就加上这个区间,遇到顶边时,就减去 ...
- 线段树+扫描线【HDU1542】Atlantis
Description 给定一些二维空间上的矩形,求它们的面积并. 一道线段树+扫描线的板子题 然而即使我会打了,也不能灵活运用这种算法.QAQ 遇到题还是不太会. 但是这种板子题还是随随便便切的. ...
- 【HDU1542】Atlantis (扫描线的经典运用)
点此看题面 大致题意: 给你\(N\)个矩形,请你求出它们覆盖的面积(重叠的面积只算一次). 扫描线 这道题是一道典型的求矩形面积并问题,是扫描线的一个经典运用.这里就不赘述了. 代码 #includ ...
- 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)
[题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...
- 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...
- 【转】ACM训练计划
[转] POJ推荐50题以及ACM训练方案 -- : 转载自 wade_wang 最终编辑 000lzl POJ 推荐50题 第一类 动态规划(至少6题, 和 必做) 和 (可贪心) (稍难) 第二类 ...
- SCI&EI 英文PAPER投稿经验【转】
英文投稿的一点经验[转载] From: http://chl033.woku.com/article/2893317.html 1. 首先一定要注意杂志的发表范围, 超出范围的千万别投,要不就是浪费时 ...
随机推荐
- 作业20171019 alpha-1成绩
申诉 对成绩有疑问或不同意见的同学,请在群里[@杨贵福]. 申诉时间截止2017年11月21日 12:00. 总结 普遍成绩有明显上升,归功于1. 团队全都超额完成1次站立会议,多数团队完超额2次; ...
- 《Linux内核设计》第17章学习笔记
- Linux内核第五节 20135332武西垚
20135332武西垚 在MenuOS中通过添加代码增加自定义的系统调用命令 使用gdb跟踪调试内核 简单分析system_call代码了解系统调用在内核代码中的处理过程 由于本周实验是在Kali虚拟 ...
- Eclipse——Note
Eclipse中常用的快捷键 快捷键 功能
- Selenium Grid的Java调用方法
java -jar selenium-server-standalone-.jar -role hub explorer http://192.168.1.173:4444/grid/console ...
- HTML5 Base64_encoding_and_decoding
https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding In JavaSc ...
- Java的Vector源码阅读
* The {@code Vector} class implements a growable array of * objects. Like an array, it contains comp ...
- jstack 使用一例
31jstack -m -F 2340 >libra.log 2>&1 jstack -m -F 2340 >libra2.log 2&>1 jstack -m ...
- PHP hexdec() 函数
hexdec() 函数把十六进制转换为十进制. 语法 hexdec(hex_string) 参数 描述 hex_string 必需.规定要转换的十六进制数. 说明 返回与 hex_string 参数所 ...
- hive分区表
分区表创建 row format delimited fields terminated by ',';指明以逗号作为分隔符 依靠插入表创建分区表 从表sample_table选择 满足分区条件的 ...