覆盖的面积

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 3553    Accepted Submission(s): 1743

Problem Description
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.





 
Input
输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N&lt;=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000.



注意:本题的输入数据较多,推荐使用scanf读入数据.
 
Output
对于每组测试数据,请计算出被这些矩形覆盖过至少两次的区域的面积.结果保留两位小数.
 
Sample Input
2
5
1 1 4 2
1 3 3 7
2 1.5 5 4.5
3.5 1.25 7.5 4
6 3 10 7
3
0 0 1 1
1 0 2 1
2 0 3 1
 
Sample Output
7.63
0.00

#include<iostream>
#include<cstdio>
#include<algorithm>
#define Max 10005
using namespace std;
struct line{
double x, y1, y2;
int flag;
}x_line[Max]; struct node{
int l, r, flag;
double x, f;
}tree[Max]; double point[Max];
int n, m, xm; int cmp(double a,double b)
{
return a<b;
} bool comp(line a,line b)
{
return a.x<b.x;
} void Build(int l,int r,int k)
{
int m;
tree[k].l = l;
tree[k].r = r;
tree[k].flag = 0;
tree[k].x = 0.0;
tree[k].f = 0.0;
if(l+1 == r) return;
m = (l+r)>>1;
Build(l,m,k+k);
Build(m,r,k+k+1);
} void Myscanf()
{
m = 1;
double x1,x2,y1,y2;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
point[m] = y1;
x_line[m].x = x1;
x_line[m].y1 = y1;
x_line[m].flag = 1;
x_line[m++].y2 = y2;
point[m] = y2;
x_line[m].x = x2;
x_line[m].y1 = y1;
x_line[m].flag = -1;
x_line[m++].y2 = y2;
} } void Point_Do()
{
int mi = 0;
sort(point+1,point+m,cmp);
sort(x_line+1,x_line+m,comp);
xm = m;
for(int i=1; i<m; i++)
{
if(point[i]!=point[mi]) point[++mi] = point[i]; //去重
}
m = mi;
} int Bin(double xi)
{
int l = 1, r = m;
int mi;
while(l<=r)
{
mi = (l+r)>>1;
if(xi == point[mi]) return mi;
if(xi > point[mi]) l = mi+1;
else r = mi-1;
}
return -1;
} void update(int l, int r, int k, line cur)
{
if(tree[k].l==tree[k].r-1)
{
if(tree[k].flag == 1 && cur.flag == 1) tree[k].f = cur.x;
else if(tree[k].flag==2 && cur.flag==-1){
tree[k].x +=( cur.x - tree[k].f );
tree[k].f = 0.0;
}
tree[k].flag+=cur.flag;
return;
}
int mi = (tree[k].l+tree[k].r)>>1;
if(l>=mi) update(l,r,k+k+1,cur);
else if(r<=mi) update(l,r,k+k,cur);
else{
update(l,mi,k+k,cur);
update(mi,r,k+k+1,cur);
}
return;
} double query(int k)
{
if(tree[k].l + 1==tree[k].r) return (point[tree[k].r]-point[tree[k].l])*tree[k].x;
return query(k+k) + query(k+k+1);
} int Ans()
{
for(int i=1;i<xm;i++)
{
int x = Bin(x_line[i].y1);
int y = Bin(x_line[i].y2);
update(x,y,1,x_line[i]);
}
} int main()
{
int Case;
scanf("%d",&Case);
while(Case--)
{
memset(tree,0,sizeof(tree));
memset(point,-1,sizeof(point));
memset(x_line,0,sizeof(x_line));
Myscanf();
Point_Do();
Build(1,m,1);
Ans();
printf("%.2lf\n",query(1));
} return 0;
}

主要思路就是将y轴离散为线段树,然后,将x轴转换为状态,其实也可以x为线段树,y为状态的

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

Poj 1255 覆盖的面积 2014-07-28 12:29 116人阅读 评论(0) 收藏的更多相关文章

  1. A Knight's Journey 分类: POJ 搜索 2015-08-08 07:32 2人阅读 评论(0) 收藏

    A Knight's Journey Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 35564 Accepted: 12119 ...

  2. 欧拉回路-Door Man 分类: 图论 POJ 2015-08-06 10:07 4人阅读 评论(0) 收藏

    Door Man Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2476 Accepted: 1001 Description ...

  3. Black Box 分类: POJ 栈和队列 2015-08-05 14:07 2人阅读 评论(0) 收藏

    Black Box Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8754 Accepted: 3599 Description ...

  4. Borg Maze 分类: POJ 2015-07-27 15:28 5人阅读 评论(0) 收藏

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9971   Accepted: 3347 Description The B ...

  5. Dirichlet's Theorem on Arithmetic Progressions 分类: POJ 2015-06-12 21:07 7人阅读 评论(0) 收藏

    Dirichlet's Theorem on Arithmetic Progressions Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  6. Self Numbers 分类: POJ 2015-06-12 20:07 14人阅读 评论(0) 收藏

    Self Numbers Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22101   Accepted: 12429 De ...

  7. Counterfeit Dollar 分类: POJ 2015-06-12 15:28 19人阅读 评论(0) 收藏

    Counterfeit Dollar Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 41559   Accepted: 13 ...

  8. Poj 2559 最大矩形面积 v单调栈 分类: Brush Mode 2014-11-13 20:48 81人阅读 评论(0) 收藏

    #include<iostream> #include<stack> #include<stdio.h> using namespace std; struct n ...

  9. java面试和笔试大全 分类: 面试 2015-07-10 22:07 10人阅读 评论(0) 收藏

    2.String是最基本的数据类型吗? 基本数据类型包括byte.int.char.long.float.double.boolean和short. java.lang.String类是final类型 ...

随机推荐

  1. [译]MongoDb生产环境注意事项

    译注: 本文是翻译MongoDB Manuel中的MongoDB Production Notes一节内容.这节内容重点关注生产环境中影响性能和可靠性的各种注意事项,值得正在部署MongoDB的工作者 ...

  2. 初识 css3中counter属性

    最近看到counter属性,好奇是做什么用的,于是去查了查. 1.简单介绍 counter是为css中插入计数器.[注明]在CSS2.1中counter()只能被使用在content属性上.关于浏览器 ...

  3. PHP计算某个目录大小的方法

    用PHP来计算某个目录大小的方法. PHP CURL session COOKIE  可以调用系统命令,还可以这样:  <?php function dirsize($dir) {  @$dh  ...

  4. char引发的血案

    char cc = 'j';cc = (char)(cc -32); //注意下,自动转型了System.out.println(cc);

  5. 任务管理界面添加显示RAM信息

    显示RAM信息的核心代码是大蛋的,我只不过是整理下教程而已! 大蛋应该不会介意的吧,首先你需要apktool和SystemUI.apk,framework-res.apk 然后开始加载框架和反编译.. ...

  6. DOS通讯录

    #include"stdio.h" #include"string.h" #include"stdlib.h" FILE *fp; #def ...

  7. 界面控件 - 滚动条ScrollBar

    界面是人机交互的门户,对产品至关重要.在界面开发中只有想不到没有做不到的,有好的想法,当然要尝试着做出来.对滚动条的扩展,现在有很多类是的例子. VS2015的代码编辑是非常强大的,其中有一个功能可以 ...

  8. Iframe 自适应高度的方法!

    第一种方法:代码简单,兼容性还可以,大家可以先测试下. function SetWinHeight(obj) { var win=obj; if (document.getElementById) { ...

  9. 使用 libevent 和 libev 提高网络应用性能——I/O模型演进变化史

    构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件,无论它们是内部请求还是网络连接,都要有效地处理它们的操作. 有许多解决方案,但事件驱动也被广泛应用到网络编程中.并大规模部署在高 ...

  10. C# 堆和栈的区别-该文转自:http://www.itcodes.cn/746.html | 程序人生

    理解堆与栈对于理解.NET中的内存管理.垃圾回收.错误和异常.调试与日志有很大的帮助.垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不代表程 ...