题目大意:给定 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的更多相关文章

  1. 【POJ1151】Atlantis(线段树,扫描线)

    [POJ1151]Atlantis(线段树,扫描线) 题面 Vjudge 题解 学一学扫描线 其实很简单啦 这道题目要求的就是若干矩形的面积和 把扫描线平行于某个轴扫过去(我选的平行\(y\)轴扫) ...

  2. 【POJ1151】【扫描线+线段树】Atlantis

    Description There are several ancient Greek texts that contain descriptions of the fabled island Atl ...

  3. 【HDU1542】Atlantis

    题意 给出n个矩形的左下角和右上角的坐标,计算总的面积(相交部分只算一次). 分析 线段树扫描线的模板题. 将每个矩形都拆成上下两条线段,然后从下网上扫,当遇到底边时就加上这个区间,遇到顶边时,就减去 ...

  4. 线段树+扫描线【HDU1542】Atlantis

    Description 给定一些二维空间上的矩形,求它们的面积并. 一道线段树+扫描线的板子题 然而即使我会打了,也不能灵活运用这种算法.QAQ 遇到题还是不太会. 但是这种板子题还是随随便便切的. ...

  5. 【HDU1542】Atlantis (扫描线的经典运用)

    点此看题面 大致题意: 给你\(N\)个矩形,请你求出它们覆盖的面积(重叠的面积只算一次). 扫描线 这道题是一道典型的求矩形面积并问题,是扫描线的一个经典运用.这里就不赘述了. 代码 #includ ...

  6. 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)

    [题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...

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

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

  8. 【转】ACM训练计划

    [转] POJ推荐50题以及ACM训练方案 -- : 转载自 wade_wang 最终编辑 000lzl POJ 推荐50题 第一类 动态规划(至少6题, 和 必做) 和 (可贪心) (稍难) 第二类 ...

  9. SCI&EI 英文PAPER投稿经验【转】

    英文投稿的一点经验[转载] From: http://chl033.woku.com/article/2893317.html 1. 首先一定要注意杂志的发表范围, 超出范围的千万别投,要不就是浪费时 ...

随机推荐

  1. RabbitMQ --- Hello Mr.Tua

    目录 RabbitMQ --- Work Queues(工作队列) RabbitMQ --- Publish/Subscribe(发布/订阅) RabbitMQ --- Routing(路由) 安装环 ...

  2. git push上传代码到gitlab上,报错401/403(或需要输入用户名和密码)

    之前部署的gitlab,采用ssh方式连接gitlab,在客户机上产生公钥上传到gitlab的SSH-Keys里,git clone下载和git push上传都没问题,这种方式很安全. 后来应开发同事 ...

  3. Hibernate_core_method

    /** * Created by Administrator on 2015/11/30. *HibernateUtil */public class HibernateUtil { private ...

  4. java — 静态绑定和动态绑定

    绑定:一个方法的调用与方法所在的类关联起来.java中的绑定分为静态绑定和动态绑定,又被称作前期绑定和后期绑定. 静态绑定:(final.static.private)在程序执行前已经被绑定,也就是说 ...

  5. Java 类的加载

    package com.cwcec.p2; class C { public static final int SIZE; static { SIZE = 100; System.out.printl ...

  6. [2017BUAA软件工程]第0次作业

    第一部分:结缘计算机 1. 你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢?(必答) 选择计算机专业的一个重要原因是因为计算机专业的就业前景好,由于计算机本身具有的各种优点,现在几乎所有的 ...

  7. Max length of title attribute in html

    测了一下chrome是1024个utf-8字符. 具体可见: http://stackoverflow.com/questions/8516235/max-length-of-title-attrib ...

  8. PHP自动加载上——spl_autoload_register

    spl_autoload_register函数是实现自动加载未定义类功能的的重要方法,所谓的自动加载意思就是 我们的new 一个类的时候必须先include或者require的类文件,如果没有incl ...

  9. yum install 报错[Errno 14] curl#37 - Couldn't open file /mnt/repodata/repomd.xml

    1.然后按照网上的一些修改,先是执行: yum cleam all 然后 yum makecache,问题还是没解决,继续报错. 其实这两条命令就是清空缓存,然后再重新缓存的意思,有时候可能有效. 2 ...

  10. Metaspace 之一:Metaspace整体介绍(永久代被替换原因、元空间特点、元空间内存查看分析方法)

    回顾 根据JVM内存区域的划分,简单的画了下方的这个示意图.区域主要分为两大块,一块是堆区(Heap),我们所New出的对象都会在堆区进行分配,在C语言中的malloc所分配的方法就是从Heap区获取 ...