Atlantis
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 19374   Accepted: 7358

Description

There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the
total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.

Input

The input 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.

Output

For 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

题意是给出诸多矩形的左下角坐标和右上角坐标,问这些矩形一共覆盖的面积。

看了真的是很久很久,终于把这道题的代码搞懂了,趁着对这道题有很多感觉,赶紧记下来。也通过这些题,发现线段树的应用范围真的是广。

实际上就是对每一段的x,求其y的长度,相乘就是对应的面积。最后把所有的面积加起来就是总面积。为了防止可能会发生重复加的面积,使用了线段树的结构。

首先是离散化,把y坐标上的浮点数 变成1 2 3 ---,然后使用对每一条边使用二分查找。

然后线段树中的每一个节点就代表了相应段的y的长度,和之前的线段树一样,线段树的思想就是我要使用哪一段的长度,我再去计算它更新它,这里面的len就代表了这个含义。

然后就是cover,cover就是只有为0的时候去更新它,因为不是0的时候代表着它依然被某个矩形覆盖着,所以不能更新成子节点的长度之和。

dele就是将原来的长度划出掉,cover--,判断为0就更新该点的len。

写到哪里算哪里,看着这段代码,觉得真的很奇妙。

代码:

#pragma warning(disable:4996)
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
using namespace std; double y[210]; struct li
{
double x,y1,y2;
bool bleft;
}lines[210]; struct no
{
int L,R;
double len;
int cover; }tree[10000]; bool operator < (const li &n1,const li &n2)
{
return n1.x<n2.x;
} template <class F,class T>
F bin_search(F s,F e,T val)
{
F L = s;
F R = e-1; while(L<=R)
{
F mid = L + (R-L)/2;
if(!(*mid<val || val < *mid))
{
return mid;
}
else if(val < *mid)
{
R = mid -1;
}
else
{
L= mid + 1;
}
}
} void buildtree(int root,int L,int R)
{
tree[root].L=L;
tree[root].R=R; tree[root].len=0;
tree[root].cover=0; if(L!=R)
{
int mid = (L+R)/2;
buildtree(root*2+1,L,mid);
buildtree(root*2+2,mid+1,R);
}
} void inse(int root,int L,int R)
{
if(tree[root].L==L&&tree[root].R==R)
{
tree[root].cover++;
tree[root].len= y[R+1] - y[L];
return;
}
int mid = (tree[root].L + tree[root].R)/2; if(R<=mid)
{
inse(root*2+1,L,R);
}
else if(L>=mid+1)
{
inse(root*2+2,L,R);
}
else
{
inse(root*2+1,L,mid);
inse(root*2+2,mid+1,R);
}
if(tree[root].cover==0)
{
tree[root].len = tree[root*2+1].len + tree[root*2+2].len;
}
} void dele(int root,int L,int R)
{
if(tree[root].L == L && tree[root].R == R)
{
tree[root].cover--;
if(tree[root].cover==0)
{
if(tree[root].L == tree[root].R)
{
tree[root].len=0;
}
else
{
tree[root].len = tree[root*2+1].len + tree[root*2+2].len;
}
}
return;
} int mid = (tree[root].L + tree[root].R)/2;
if(R<=mid)
{
dele(root*2+1,L,R);
}
else if(L>=mid+1)
{
dele(root*2+2,L,R);
}
else
{
dele(root*2+1,L,mid);
dele(root*2+2,mid+1,R);
} if(tree[root].cover==0)
{
tree[root].len = tree[root*2+1].len + tree[root*2+2].len;
}
}
int n; int main()
{
int i,yc,lc,t;
double x1,x2,y1,y2;
t=0;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
t++;
yc=0;
lc=0;
for(i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
y[yc++]=y1;
y[yc++]=y2; lines[lc].x=x1;
lines[lc].y1=y1;
lines[lc].y2=y2;
lines[lc].bleft=true;
lc++; lines[lc].x=x2;
lines[lc].y1=y1;
lines[lc].y2=y2;
lines[lc].bleft=false;
lc++;
}
sort(lines,lines+lc);
sort(y,y+yc);
yc=unique(y,y+yc)-y; buildtree(0,0,yc-1-1);
double Area=0; for(i=0;i<lc-1;i++)
{
int L=bin_search(y,y+yc,lines[i].y1)-y;
int R=bin_search(y,y+yc,lines[i].y2)-y; if(lines[i].bleft)
{
inse(0,L,R-1);
}
else
{
dele(0,L,R-1);
}
Area += tree[0].len*(lines[i+1].x-lines[i].x);
}
printf("Test case #%d\n",t);
printf("Total explored area: %.2lf\n",Area);
printf("\n");
} //system("pause");
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

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

  1. POJ 1151 - Atlantis 线段树+扫描线..

    离散化: 将所有的x轴坐标存在一个数组里..排序.当进入一条线段时..通过二分的方式确定其左右点对应的离散值... 扫描线..可以看成一根平行于x轴的直线..至y=0开始往上扫..直到扫出最后一条平行 ...

  2. hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]

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

  3. POJ 1151 Atlantis 线段树求矩形面积并 方法详解

    第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...

  4. POJ 1151 Atlantis 线段树+离散化+扫描线

    这次是求矩形面积并 /* Problem: 1151 User: 96655 Memory: 716K Time: 0MS Language: G++ Result: Accepted */ #inc ...

  5. hdu1542 Atlantis 线段树--扫描线求面积并

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

  6. HDU 1542 - Atlantis - [线段树+扫描线]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  7. HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)

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

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

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

  9. POJ1151 Atlantis 线段树扫描线

    扫描线终于看懂了...咕咕了快三个月$qwq$ 对于所有的横线按纵坐标排序,矩阵靠下的线权值设为$1$,靠上的线权值设为$-1$,然后执行线段树区间加减,每次的贡献就是有效宽度乘上两次计算时的纵坐标之 ...

随机推荐

  1. Android 学习笔记四:创建工具栏按钮

    原文:http://blog.csdn.net/lihongxun945/article/details/48951199 前面我们已经可以在一个Activity中添加一些按钮之类的组件.由于手机的屏 ...

  2. checkbox 选中获取值

    1:jsp 页面 从页面获取checkbox 的值传到后台 <div id="divCheckbox" class="hide"> <tr&g ...

  3. Hexo引入Mermaid流程图和MathJax数学公式

    近来用Markdown写文章,越来越不喜欢插入图片了,一切能用语法解决的问题坚决不放图,原因有二: 如果把流程图和数学公式都以图片方式放到文章内,当部署到Github上后,访问博客时图片加载实在太慢, ...

  4. CS231n -Assignments 1 Q1 and Q2

    前言 最近在youtube 上学习CS231n的课程,并尝试完成Assgnments,收获很多,这里记录下过程和结果以及过程中遇到的问题,我并不是只是完成需要补充的代码段,对于自己不熟悉的没用过的库函 ...

  5. windows XAMPP下安装mongoDB

    1.下载 下载地址:http://www.mongodb.org/downloads 2.安装 进入cmd第一步:D:\xampp\mongodb\bin\mongod.exe --dbpath=D: ...

  6. Dubbo与SpringBoot整合流程(从实例入手,附代码下载)

    场景 Dubbo环境搭建-管理控制台dubbo-admin实现服务监控: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10362 ...

  7. Python中from scipy.misc import imread报错的原因?

    from scipy.misc import imread 报错 查询后其原因是from scipy.misc import imread,imwrite 等方法已经被弃用,Python已经将imre ...

  8. eclipse不能启动,An internal error occurred during: "reload maven project".

    An internal error occurred during: "reload maven project". 这个错误是因为项目已经关闭,导致 导致此问题的原因是Sprin ...

  9. java学习-初级入门-面向对象③-类与对象-类与对象的定义和使用1

    今天学习类与对象.先大致解释一下类与对象的含义. 对象:object 有物体这一概念,一切皆对象(物体),对象由静态的属性和动态的行为组成. 比如说水杯: 水杯的静态属性:材质,容量,质量,颜色 动态 ...

  10. Mybatis入门(六)联查之一对多

    上一章说了多对一,很多学生被一个老师教,这一章是一个老师教很多学生 目录基本没有变化只是改了配置文件: 2.配置文件: TeacherMapper接口类: package com.hdlf.dao; ...