题目链接:http://poj.org/problem?id=1151

题意是平面上给你n个矩形,让你求矩形的面积并。

首先学一下什么是扫描线:http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html

这是别人的blog,写的挺好的。然后明白扫描线之后呢,接下来就很简单了,只需要一次一次求面积然后累加就好了。这题离散化之后,数据的范围更小了(因为n只有100),单点更新就行了。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int MAXN = 2e2 + ;
struct data {
double x1 , x2;
double y;
int xx1 , xx2 , flag; //flag: 1表示加 -1表示减 xx1 xx2是离散化之后的值
bool operator <(const data& cmp) const {
return y < cmp.y;
}
}edge[MAXN << ];
struct segtree {
int l , r , lazy; //lazy表示累加的次数
double val; //val表示长度
}T[MAXN << ];
double x[MAXN];
map <double , int> mp; double min(double a , double b) {
return a > b ? b : a;
} double max(double a , double b) {
return a > b ? a : b;
} void init(int p , int l , int r) {
int mid = (l + r) >> ;
T[p].l = l , T[p].r = r , T[p].val = T[p].lazy = ;
if(r - l == ) {
return ;
}
init(p << , l , mid);
init((p << )| , mid , r);
} void updata(int p , int l , int r , int val) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].r - T[p].l == ) {
if(val == -) {
T[p].lazy--;
T[p].val = T[p].lazy ? (x[T[p].r] - x[T[p].l]) : ;
}
else {
T[p].lazy++;
T[p].val = (x[T[p].r] - x[T[p].l]);
}
return ;
}
if(r <= mid) {
updata(p << , l , r , val);
}
else if(l >= mid) {
updata((p << )| , l , r , val);
}
else {
updata(p << , l , mid , val);
updata((p << )| , mid , r , val);
}
T[p].val = T[p << ].val + T[(p << )|].val;
} int main()
{
int n , ca = ;
double x1 , x2 , y1 , y2;
while(~scanf("%d" , &n) && n) {
int cont = ;
mp.clear();
for(int i = ; i < n ; i++) {
scanf("%lf %lf %lf %lf" , &x1 , &y1 , &x2 , &y2);
edge[i * ].x1 = min(x1 , x2) , edge[i * ].x2 = max(x1 , x2);
edge[i * ].y = min(y1 , y2);
edge[i * ].flag = ;
edge[i * + ].x1 = edge[i * ].x1 , edge[i * + ].x2 = edge[i * ].x2;
edge[i * + ].y = max(y1 , y2);
edge[i * + ].flag = -;
if(!mp[x1]) {
x[++cont] = x1;
mp[x1]++;
}
if(!mp[x2]) {
x[++cont] = x2;
mp[x2]++;
}
}
sort(edge , edge + n * );
sort(x + , x + cont + );
for(int i = ; i < n * ; i++) {
int pos = (lower_bound(x + , x + cont + , edge[i].x1) - x);
edge[i].xx1 = pos;
pos = (lower_bound(x + , x + cont + , edge[i].x2) - x);
edge[i].xx2 = pos;
}
init( , , cont);
double res = ;
updata( , edge[].xx1 , edge[].xx2 , edge[].flag);
for(int i = ; i < n * ; i++) {
res += T[].val * (edge[i].y - edge[i - ].y);
updata( , edge[i].xx1 , edge[i].xx2 , edge[i].flag);
}
printf("Test case #%d\n" , ca++);
printf("Total explored area: %.2f\n\n" , res);
}
}

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

  1. POJ 1151 Atlantis(线段树-扫描线,矩形面积并)

    题目链接:http://poj.org/problem?id=1151 题目大意:坐标轴上给你n个矩形, 问这n个矩形覆盖的面积 题目思路:矩形面积并. 代码如下: #include<stdio ...

  2. poj 1151 (未完成) 扫描线 线段树 离散化

    #include<iostream> #include<vector> #include<cmath> #include<algorithm> usin ...

  3. POJ 1151 Atlantis(扫描线)

    题目原链接:http://poj.org/problem?id=1151 题目中文翻译: POJ 1151 Atlantis Time Limit: 1000MS   Memory Limit: 10 ...

  4. poj1151 Atlantis——扫描线+线段树

    题目:http://poj.org/problem?id=1151 经典的扫描线问题: 可以用线段树的每个点代表横向被矩形上下边分割开的每一格,这样将一个矩形的出现或消失化为线段树上的单点修改: 每个 ...

  5. POJ 1542 Atlantis(线段树 面积 并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 参考网址:http://blog.csdn.net/sunmenggmail/article/d ...

  6. 【POJ】1151 Atlantis(线段树)

    http://poj.org/problem?id=1151 经典矩形面积并吧.....很简单我就不说了... 有个很神的地方,我脑残没想到: 将线段变成点啊QAQ这样方便计算了啊 还有个很坑的地方, ...

  7. [HDU1542]Atlantis(扫描线+线段树)

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

  8. HDU 1828 / POJ 1177 Picture (线段树扫描线,求矩阵并的周长,经典题)

    做这道题之前,建议先做POJ 1151  Atlantis,经典的扫描线求矩阵的面积并 参考连接: http://www.cnblogs.com/scau20110726/archive/2013/0 ...

  9. poj 3277 City Horizon (线段树 扫描线 矩形面积并)

    题目链接 题意: 给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积. 分析: 给的区间的范围很大,所以需要离散化,还需要把y坐标去重,不过我试了一下不去重 也不 ...

随机推荐

  1. HDU 4869 Turn the pokers (2014 Multi-University Training Contest 1)

    Turn the pokers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  2. UVa 10674 (求两圆公切线) Tangents

    题意: 给出两个圆的圆心坐标和半径,求这两个圆的公切线切点的坐标及对应线段长度.若两圆重合,有无数条公切线则输出-1. 输出是按照一定顺序输出的. 分析: 首先情况比较多,要一一判断,不要漏掉. 如果 ...

  3. SQL2008 R2 主从数据库同步设置

    一.准备工作: 主数据库服务器: OS:Windows Server 2008 R2    DB: SQL Server 2008 R2 Hostname : CXMasterDB IP: 192.1 ...

  4. facebook海量图片存储系统与淘宝TFS系统比较

    本篇论文的原文可谓通俗易懂.行云流水.结构清晰.图文并茂……正如作者所说的——"替换Facebook的图片存储系统就像高速公路上给汽车换轮子,我们无法去追求完美的设计……我们花费了很多的注意 ...

  5. Jquery 弹出提示框输入插件 apprise 修改中文按钮以及使用说明

      apprise的使用非常简单,引入js脚本和css <script type="text/javascript" src="/js/apprise-1.5.fu ...

  6. Android ashmem hacking

    /********************************************************************** * Android ashmem hacking * 声 ...

  7. apache多站点配置+多端口配置

    Apache多站点配置 这种方法是配置不同的地址访问不同的文件夹的配置 1:修改本机的hosts文件,如下: 示例: 127.0.0.1 localhost 127.0.0.1 www.dede.co ...

  8. phpDoc 注释案例说明

    <?php /** * start page for webaccess * * PHP version 5 * * @category PHP * @package PSI_Web * @au ...

  9. Oracle中获取执行计划的几种方法分析

    以下是对Oracle中获取执行计划的几种方法进行了详细的分析介绍,需要的朋友可以参考下     1. 预估执行计划 - Explain PlanExplain plan以SQL语句作为输入,得到这条S ...

  10. javascript中常用数组函数

    1.split方法——通过分隔符,将字符串分割,导出字符数组 常用于:分割IP地址,分割文件路径(上传文件时)等等 <!DOCTYPE html PUBLIC "-//W3C//DTD ...