线段树---Atlantis
题目网址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110064#problem/A
Description
Input
The input file is terminated by a line containing a single 0. Don't process it.
Output
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 题意: 给了n个矩形的左下角和右上角的坐标,求矩形面积的并(矩形可能覆盖在一起,求总面积); 思路:使用线段树记录所有矩形上下两条边的高度,用结构体数组记录矩形的左右两条边,并按照从左往右的顺序排序,从左到右加上每一个小矩形的面积。

代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#define N 210
using namespace std;
double y[N]; struct node
{
double x,y1,y2;
int f;
}Line[N]; struct node1
{
double lf,rf,cnt;
int l,r,c;
}tree[N*]; int cmp1(const node a,const node b)
{
return a.x < b.x;
} int cmp2(const void *a,const void *b)
{
return *(double *)a>*(double *)b?:-;
} void bulid(int t,int l,int r)
{
int mid;
tree[t].c=; tree[t].cnt=;
tree[t].l=l;
tree[t].r=r;///记录着所有矩形的两条竖边从左到右的顺序编号;
tree[t].lf=y[l];
tree[t].rf=y[r];
if(l+==r) return;
mid=(l+r)/;
bulid(*t,l,mid);
bulid(*t+,mid,r);
} void calen(int t)
{
if(tree[t].c>)
{
tree[t].cnt=tree[t].rf-tree[t].lf;
return ;
}
if(tree[t].l+==tree[t].r) tree[t].cnt=;///是矩形右面的边则将树节点的值清零;
else tree[t].cnt=tree[*t].cnt+tree[*t+].cnt;///计算父节点的值;
} void updata(int t,node e)
{
if(e.y1 == tree[t].lf && e.y2==tree[t].rf)
{
tree[t].c+=e.f;
calen(t);
return;
}
if(e.y2 <=tree[*t].rf ) updata(*t,e);
else if(e.y1 >=tree[*t+].lf) updata(*t+,e);
else
{
node tmp=e;
tmp.y2=tree[*t].rf;
updata(*t,tmp);
tmp=e;
tmp.y1=tree[*t+].lf;
updata(*t+,tmp);
}
calen(t);///计算各个父节点的cnt值;
} int main()
{
int Case=,n,t;
double x1,y1,x2,y2,ans;
while(scanf("%d",&n)!=EOF && n)
{
Case++;
t=;
for(int i=;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
Line[t].x=x1;
Line[t].y1=y1;
Line[t].y2=y2;
Line[t].f=;
y[t]=y1; Line[t+].x=x2;
Line[t+].y1=y1;
Line[t+].y2=y2;
Line[t+].f=-;
y[t+]=y2;
t+=;
}
sort(Line+,Line+t-,cmp1);///对结构体Line按x值从小到大进行排序;
qsort(y+,t-,sizeof(y[]),cmp2);///对y[]数组进行从小到大的排序;
bulid(,,t-);
ans=;
for(int i=;i<t;i++)
{
ans+=tree[].cnt*(Line[i].x - Line[i-].x);
updata(,Line[i]);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",Case,ans);
}
return ;
}
线段树---Atlantis的更多相关文章
- hdu 1542 Atlantis(线段树,扫描线)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- POJ 1542 Atlantis(线段树 面积 并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 参考网址:http://blog.csdn.net/sunmenggmail/article/d ...
- 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)
[题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...
- 【POJ1151】Atlantis(线段树,扫描线)
[POJ1151]Atlantis(线段树,扫描线) 题面 Vjudge 题解 学一学扫描线 其实很简单啦 这道题目要求的就是若干矩形的面积和 把扫描线平行于某个轴扫过去(我选的平行\(y\)轴扫) ...
- hdu1542 Atlantis 线段树--扫描线求面积并
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...
- HDU 1542 Atlantis(线段树面积并)
描述 There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. S ...
- hdu1542 Atlantis (线段树+扫描线+离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1542 - Atlantis - [线段树+扫描线]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
随机推荐
- Swift:如何判断一个对象是否是某个类(或其子类)的实例
在OC中我们直接可以用如下方法即可 [obj isKindOfClass:[obj class]]; 在Swift中,并没有 .class 属性或者方法, 便可以用如下方法 class Person ...
- (转)新手必看:HighCharts几个基础问答
转自:http://bbs.hcharts.cn/article-21-1.html
- WinForm 批量设置指定控件中的控件状态
在开发中常遇到当点击某个按钮的时候,禁用文本框或按钮的的状态,以防止误操作,下面的代码是我已批量设置指定控件中的按钮状态的代码,同理可以延伸出很多操作. /// <summary> /// ...
- JSON跨域请求
原理:首先客户机会注册一个callback,在发送跨域请求之前,会在url后附带注册的callback参数(如:callback1982342322),随后服务器拿到了callback参数,获取数据后 ...
- tomcat的网站屏蔽IP的方法
<Host> <Valve className="org.apache.catalina.valves.RemoteAddrValve" deny=" ...
- HDU 3487 Play with Chain(Splay)
题目大意 给一个数列,初始时为 1, 2, 3, ..., n,现在有两种共 m 个操作 操作1. CUT a b c 表示把数列中第 a 个到第 b 个从原数列中删除得到一个新数列,并将它添加到新数 ...
- ubuntu关闭自动更新、打开 ubuntu 的 apport 崩溃检测报告功能
菜单栏点 系统 --->首选项 --->启动应用程序 --->更新提示 前面的钩打掉 关闭即可 =========== 打开 ubuntu 的 apport 崩溃检测报告功能 ...
- 如何生成ipa文件
xcode--Product--Archive 弹出Organizer-Archives选择Distribute---Save for EnterPrise or Ad_Hoc Deployment- ...
- wndbg下载与安装
wndbg分X86和X64两个版本 如果你的程序是32位的,就下载安装X86的版本:如果你的程序是64位,就下载X64版本. x86位版本下载:[微软官方安装版] x64位版本下载:[微软官方安装版]
- access里like的通配符不能用%,要用*
转自http://www.knowsky.com/339881.html access里like的通配符用法是这样: “?”表示任何单一字符: “*”表示零个或多个字符: “#”表示任何一个数 ...