POJ 1151 - Atlantis 线段树+扫描线..
离散化: 将所有的x轴坐标存在一个数组里..排序.当进入一条线段时..通过二分的方式确定其左右点对应的离散值...
扫描线..可以看成一根平行于x轴的直线..至y=0开始往上扫..直到扫出最后一条平行于x轴的边..但是真正在做的时候..不需要完全模拟这个过程..扫描线的做法是从最下面的边开始扫到最上面的边.
线段树: 本题用于动态维护扫描线在往上走时..x哪些区域是有合法面积的..
几个图说明扫描线扫描..线段树维护的过程..:
初始状态
扫到最下边的线,点更新1~3为1
扫到第二根线,此时将计数器不为0的长度*上线两根线的长度,得到绿色的面积,加到答案中去.随后更新计数
同上,将黄色的面积加到答案中去
同上,将灰色的面积加到答案中去
同上,将紫色的面积加到答案中去
同上,将蓝色的面积加到答案中去
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<set>
#include <ctime>
#include<queue>
#include<algorithm>
#include<cmath>
#define oo 1000000007
#define ll long long
#define pi acos(-1.0)
#define MAXN 405
using namespace std;
struct node
{
double l,r,y;
int tp;
bool operator <(node a) const
{
return y<a.y;
}
}line[MAXN<<2];
int n,Times[MAXN<<2];
double X[MAXN<<2],sum[MAXN];
int b_search(double x)
{
int l,r,mid;
l=0,r=n+1;
while (r-l>1)
{
mid=(l+r)>>1;
if (X[mid]<=x) l=mid;
else r=mid;
}
return l;
}
void update(int x,int c,int l,int r,int now)
{
if (l==r)
{
Times[x]+=c;
if (Times[x]) sum[now]=X[x+1]-X[x];
if (!Times[x]) sum[now]=0;
return;
}
int mid=(l+r)/2;
if (x<=mid) update(x,c,l,mid,now<<1);
if (mid<x) update(x,c,mid+1,r,(now<<1)|1);
sum[now]=sum[now<<1]+sum[(now<<1)|1];
return;
}
int main()
{
int i,j,num,T=0;
double ans=0;
while (~scanf("%d",&n) && n)
{
num=0;
for (i=1;i<=n;i++)
{
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
line[i*2-1].y=y1,line[i*2-1].l=x1,line[i*2-1].r=x2,line[i*2-1].tp=1;
line[i*2].y=y2,line[i*2].l=x1,line[i*2].r=x2,line[i*2].tp=-1;
X[++num]=x1,X[++num]=x2;
}
n=n*2;
sort(X+1,X+1+num);
sort(line+1,line+1+n);
memset(sum,0,sizeof(sum));
memset(Times,0,sizeof(Times));
ans=0;
for (i=1;i<=n;i++)
{
ans+=sum[1]*(line[i].y-line[i-1].y);
int l,r;
l=b_search(line[i].l);
r=b_search(line[i].r)-1;
for (j=l;j<=r;j++) update(j,line[i].tp,1,n-1,1);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",++T,ans);
}
return 0;
}
POJ 1151 - Atlantis 线段树+扫描线..的更多相关文章
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- POJ 1151 Atlantis 线段树求矩形面积并 方法详解
第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...
- POJ 1151 Atlantis 线段树+离散化+扫描线
这次是求矩形面积并 /* Problem: 1151 User: 96655 Memory: 716K Time: 0MS Language: G++ Result: Accepted */ #inc ...
- 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 ...
- POJ 1151:Atlantis 线段树+扫描线
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19374 Accepted: 7358 Descrip ...
- 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) ...
- POJ1151 Atlantis 线段树扫描线
扫描线终于看懂了...咕咕了快三个月$qwq$ 对于所有的横线按纵坐标排序,矩阵靠下的线权值设为$1$,靠上的线权值设为$-1$,然后执行线段树区间加减,每次的贡献就是有效宽度乘上两次计算时的纵坐标之 ...
随机推荐
- Python自动化运维之3、函数、lambda、递归
一.函数 函数的基础概念: 函数是python为了代码最大程度地重用和最小化代码冗余而提供的基本结构 函数是一种设计工具,它能让程序员将复杂的系统分解为可管理的部件 函数用于将相关功能打包并参数化 在 ...
- 11061160顾泽鹏homework-01
我的Github地址是buaa11061160 教材:中文版 代码大全 (第二版) 斯蒂夫·迈克康奈尔 设计思路: 输入了一串数组a[0].a[1]..... 从a[0]开始向后扫,在以数字a[i]结 ...
- Asp.net Core 缓存 MemoryCache 和 Redis
Asp.net Core 缓存 MemoryCache 和 Redis 目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 经过 N 久反复的尝试,翻阅了网上无数的资料,GitH ...
- Codeforces739E Gosha is hunting
题意:现在有n个精灵,两种精灵球各m1和m2个,每个精灵单独使用第一种精灵球有pi的概率被捕获,单独使用第二种精灵球有ui的概率被捕获,同时使用有1-(1-pi)*(1-ui)的概率被捕获.一种精灵球 ...
- IDEA启动自动进入最后一个项目
每次打开IDEA的时候总会加载上级最后打开的工程,可能这个工程并不是我需要的,我就得重新去打开我需要的工程,感觉这一点非常鸡肋. 使用如下方法可以在启动的时候,选择启动哪个工程,而不是直接进入. Fi ...
- Swift—扩展声明-备
声明扩展的语法格式如下: extension 类型名 { //添加新功能 } 声明扩展的关键字是extension,“类型名”是Swift中已有的类型,包括类.结构体和枚举,但是我们仍然可以扩展整型. ...
- Android中layout_weight的属性理解
https://www.zybuluo.com/zzudhj/note/102067 在Android开发过程中,在编写布局文件经常会用layout_weight属性:从字面意思上看权重.比值.按比例 ...
- Linux格式化分区报错Could not start /dev/sda No such file or directory 解决办法
Linux查看已经分好的区[root@linuxidc ~]# fdisk -l /dev/sda Disk /dev/sda: 21.5 GB, 21474836480 bytes 255 he ...
- android上传图片至服务器
本实例实现了android上传手机图片至服务器,服务器进行保存 服务器servlet代码publicvoid doPost(HttpServletRequest request, HttpServle ...
- 关于Action返回结果类型的事儿(下)
原文:关于Action返回结果类型的事儿(下) using System; using System.Collections.Generic; using System.Linq; using ...