zoukankan      html  css  js  c++  java
  • HDU 1255 覆盖的面积

    覆盖的面积

    Time Limit: 5000ms
    Memory Limit: 32768KB
    This problem will be judged on HDU. Original ID: 1255
    64-bit integer IO format: %I64d      Java class name: Main
    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.


     

    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

    解题:离散化,扫面线求矩形面积的交。。关键是如何更新覆盖两次以上的区间。

    如果当前区间覆盖次数超过一次,那么区间长度就是差了,如果覆盖次数是1呢,那么看左儿子与右儿子,覆盖至少一次的长度,这两个加起来,即覆盖至少两次的长度。。。。

    其余的跟一般的求面积并没什么区别了。。。

    ps:此题的题面貌似有误,应该是先左下角,再右上角,还有第一个样例保留两位小数貌似是7.62.。。


     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 100000;
     4 struct node{
     5     int lt,rt,cover;
     6     double s,ss;
     7 }tree[maxn<<2];
     8 struct Line{
     9     double x1,x2,y;
    10     int delta;
    11     Line(){}
    12     Line(double xx,double xxx,double yy,int dt){
    13         x1 = xx;
    14         x2 = xxx;
    15         y = yy;
    16         delta = dt;
    17     }
    18     bool operator<(const Line &t)const{
    19         return y < t.y;
    20     }
    21 };
    22 vector<Line>line;
    23 vector<double>d;
    24 void build(int lt,int rt,int v){
    25     tree[v].lt = lt;
    26     tree[v].rt = rt;
    27     tree[v].cover = 0;
    28     tree[v].s = tree[v].ss = 0;
    29     if(lt + 1 == rt) return;
    30     int mid = (lt + rt)>>1;
    31     build(lt,mid,v<<1);
    32     build(mid,rt,v<<1|1);
    33 }
    34 void pushUp(int v){
    35     if(tree[v].cover) tree[v].s = d[tree[v].rt] - d[tree[v].lt];
    36     else if(tree[v].lt + 1 == tree[v].rt) tree[v].s = 0;
    37     else tree[v].s = tree[v<<1].s + tree[v<<1|1].s;
    38 
    39     if(tree[v].cover > 1) tree[v].ss = d[tree[v].rt] - d[tree[v].lt];
    40     else if(tree[v].lt + 1 == tree[v].rt) tree[v].ss = 0;
    41     else if(tree[v].cover == 1) tree[v].ss = tree[v<<1].s + tree[v<<1|1].s;
    42     else tree[v].ss = tree[v<<1].ss + tree[v<<1|1].ss;
    43 }
    44 void update(int lt,int rt,int delta,int v){
    45     if(lt <= tree[v].lt && rt >= tree[v].rt){
    46         tree[v].cover += delta;
    47         pushUp(v);
    48         return;
    49     }
    50     if(lt < tree[v<<1].rt) update(lt,rt,delta,v<<1);
    51     if(rt > tree[v<<1|1].lt) update(lt,rt,delta,v<<1|1);
    52     pushUp(v);
    53 }
    54 int main(){
    55     int T,n;
    56     double x1,y1,x2,y2;
    57     scanf("%d",&T);
    58     while(T--){
    59         scanf("%d",&n);
    60         line.clear();
    61         d.clear();
    62         for(int i = 0; i < n; ++i){
    63             scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
    64             d.push_back(x1);
    65             d.push_back(x2);
    66             line.push_back(Line(x1,x2,y1,1));
    67             line.push_back(Line(x1,x2,y2,-1));
    68         }
    69         sort(line.begin(),line.end());
    70         sort(d.begin(),d.end());
    71         d.erase(unique(d.begin(),d.end()),d.end());
    72         double ret = 0;
    73         build(0,d.size()-1,1);
    74         for(int i = 0; i < line.size(); ++i){
    75             if(i) ret += (line[i].y - line[i-1].y)*tree[1].ss;
    76             int x = lower_bound(d.begin(),d.end(),line[i].x1)-d.begin();
    77             int y = lower_bound(d.begin(),d.end(),line[i].x2)-d.begin();
    78             update(x,y,line[i].delta,1);
    79         }
    80         printf("%.2f
    ",ret);
    81     }
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    C++11 lambda表达式(lambda expression)
    win 10 relog.exe 下载地址
    检测闩锁/自旋锁争用
    关于sql 锁和并发的一些记录
    FAST number_rows 意义解释
    网站实施SEO的步骤
    搜索引擎高级搜索指令浅析
    关于遇到高并发时候的一些总结
    Autofac 设置方法拦截器的两种方式
    C# MVC 进入Action 方法之后怎么使用MVC参数验证模型
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4487942.html
Copyright © 2011-2022 走看看