HDU1255 扫描线 矩形交面积 离散化
2024-09-27 10:09:49
覆盖的面积
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5595 Accepted Submission(s): 2810
Problem Description
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.
Input
输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=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
Author
Ignatius.L & weigang Lee
题意:
给出矩形左下和右上角的坐标,求矩形交的面积。
代码:
//cnt[rt]>=2的一定是覆盖过两次以上的,直接计算。cnt[rt]==1时,如果rt的左右儿子
//被覆盖过大于等于1次,那么再被他们父亲覆盖上就是覆盖过两次了,值是左右儿子被
//覆盖过一次的长度的和。cnt[rt]==0照常更新。sum2记录覆盖过两次以上的边的长度。
//sum1记录覆盖过一次的边的长度。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
double sum1[maxn*],sum2[maxn*],mp[maxn];
int cnt[maxn*];
struct node{
double l,r,h;
int d;
node(){}
node(double a,double b,double c,int d):l(a),r(b),h(c),d(d){}
bool operator < (const node &p)const{
if(h==p.h) return d>p.d;
return h<p.h;
}
}nodes[maxn*];
int Bsearch(double a,int b,double *c)
{
int l=,r=b-,mid;
while(l<=r){
mid=(l+r)>>;
if(c[mid]==a) return mid;
else if(c[mid]>a) r=mid-;
else l=mid+;
}
return -;
}
void Pushup(int l,int r,int rt)
{
if(cnt[rt]){
sum1[rt]=mp[r+]-mp[l];
if(cnt[rt]==)
sum2[rt]=sum1[rt<<]+sum1[rt<<|];
else sum2[rt]=mp[r+]-mp[l];
}
else if(l==r) sum1[rt]=sum2[rt]=;
else{
sum1[rt]=sum1[rt<<]+sum1[rt<<|];
sum2[rt]=sum2[rt<<]+sum2[rt<<|];
}
}
void Update(int ql,int qr,int v,int l,int r,int rt)
{
if(ql<=l&&qr>=r){
cnt[rt]+=v;
Pushup(l,r,rt);
return;
}
//if(l==r) return;
int m=(l+r)>>;
if(ql<=m) Update(ql,qr,v,l,m,rt<<);
if(qr>m) Update(ql,qr,v,m+,r,rt<<|);
Pushup(l,r,rt);
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int m=,nu=;
double x1,y1,x2,y2;
memset(sum1,,sizeof(sum1));
memset(sum2,,sizeof(sum2));
memset(cnt,,sizeof(cnt));
for(int i=;i<n;i++){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
nodes[m++]=node(x1,x2,y1,);
nodes[m++]=node(x1,x2,y2,-);
mp[nu++]=x1;mp[nu++]=x2;
}
sort(mp,mp+nu);
nu=unique(mp,mp+nu)-mp;
sort(nodes,nodes+m);
double ans=;
for(int i=;i<m-;i++){
int lef=Bsearch(nodes[i].l,nu,mp);
int rig=Bsearch(nodes[i].r,nu,mp)-;
if(lef<=rig)
Update(lef,rig,nodes[i].d,,nu-,);
ans+=sum2[]*(nodes[i+].h-nodes[i].h);
}
printf("%.2lf\n",ans);
}
return ;
}
最新文章
- FFmpeg学习5:多线程播放视音频
- 一个轻量级分布式RPC框架--NettyRpc
- 在C#中使用消息队列RabbitMQ
- 2015.1.25 Delphi打开网址链接的几种方法
- 精通 CSS 选择器(二)
- Jquery——思维导图
- MyBatis关联查询分页
- C语言中强制数据类型转换(转)
- java传输json数据用md5加密过程
- linux - 怎么自动填写有交互的shell脚本 - SegmentFault
- Linux-Tcp-IP
- 【Elasticsearch全文搜索引擎实战】之集群搭建及配置
- 机器学习入门06 - 训练集和测试集 (Training and Test Sets)
- mysql 使用注意
- [MapReduce_add_1] Windows 下开发 MapReduce 程序部署到集群
- Ubuntu 安装 OpenMPI
- java安全删除一个文件,防止工具恢复数据
- 牛客网数据库SQL实战(6-10)
- HTTP中Get、Post、Put与Delete。了解一下!
- [z]oracle优化http://jadethao.iteye.com/blog/1613943