hdu 1255 覆盖的面积

覆盖的面积


有不懂得地方 参见面积并 那道题目
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<stdio.h> #include<stdlib.h> #include<algorithm> using namespace std; struct Line { double x1; double x2; double h; int cover; }line[100000]; struct Node { int left; int right; double once; double more; int cover; }node[100000]; double xx[100000]; /// int cmp(const void *a,const void *b) { return (*(struct Line *)a).h>(*(struct Line *)b).h?1:-1;//从小到大排列 } void build(int left,int right,int nd) { node[nd].left=left; node[nd].right=right; node[nd].cover=0; node[nd].more=0; node[nd].once=0; if(left==right) return ; int mid=(left+right)/2; build(left,mid,nd*2); build(mid+1,right,nd*2+1); } void update(int t) { if( node[t].cover >= 2 ) { node[t].once = 0; node[t].more = xx[node[t].right+1] - xx[node[t].left]; return ; } if( node[t].cover == 1 ) { //覆盖一次 则覆盖两次的长度为儿子覆盖一次和两次的长度之和 覆盖一次的长度则为总长度减去覆盖多次的长度 因为不可能存在没被覆盖的区域 if( node[t].left == node[t].right ) node[t].more = 0; else node[t].more = node[t*2].more+ node[t*2+1].more + node[t*2].once + node[t*2+1].once;//当前节点覆盖一次 但是儿子节点之前覆盖了一次的现在又覆盖了一次 故变成了新的覆盖的2次 node[t].once = xx[node[t].right+1] -xx[node[t].left] - node[t].more; return ; } if( node[t].cover == 0 ) { if( node[t].left == node[t].right ) node[t].more = node[t].once = 0; else { node[t].more = node[t*2].more + node[t*2+1].more; node[t].once = node[t*2].once + node[t*2+1].once; } return ; } } void insert(int left,int right,int cover,int nd) { if(left==node[nd].left&&right==node[nd].right) { node[nd].cover+=cover; update(nd); return ; } int mid=(node[nd].left+node[nd].right)/2; if(right<=mid) insert(left,right,cover,nd*2); else if(left>mid) insert(left,right,cover,nd*2+1); else { insert(left,mid,cover,nd*2); insert(mid+1,right,cover,nd*2+1); } update(nd); } int bsearch(int p,int q,double c) { while(p<=q){ int mid=(p+q)/2; if(xx[mid]==c) return mid; if(xx[mid]<c) p=mid+1; else q=mid-1; } return -1; } int main() { int cas,n,k,i,j; scanf("%d",&cas); while(cas--) { scanf("%d",&n); k=0; for(i=0;i<n;i++) { double x1,y1,x2,y2; scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); line[k].x1=x1; line[k].x2=x2; line[k].cover=1; line[k].h=y1; xx[k]=x1; k++; line[k].x1=x1; line[k].x2=x2; line[k].cover=-1; line[k].h=y2; xx[k]=x2; k++; } sort(xx,xx+k); qsort(line,k,sizeof(line[0]),cmp); j=k;k=1;//j条边 for(i=1;i<j;i++) { if(xx[i]!=xx[i-1]) xx[k++]=xx[i]; } k--; build(0,k,1); double ans=0; for(i=0;i<j-1;i++)//j-1 哦 { int left,right; left=bsearch(0,k,line[i].x1); right=bsearch(0,k,line[i].x2)-1; if(right<left)//两个点重复时,特殊处理! 这里其实额也搞不懂 去掉也能过 估计是测试数据里没有这样的数据 { ans+=(line[i+1].h-line[i].h)*node[1].more; continue; } insert(left,right,line[i].cover,1); ans+=(line[i+1].h-line[i].h)*node[1].more; } printf("%.2lf\n",ans); } return 0; }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值