• 线段树区间扫描线(hdu 1542)


    题意描述:

    给定一个矩阵,输入为左上角和右下角,现在要计算出所有矩阵重叠之后的面积总和。

    解题思路:

    根据x轴或者y轴建树,不过数据如果够大,必须先离散化,利用扫描线记录当前区间已经被覆盖的长度,那么现在覆盖的长度乘以下一条线段的距离,这个面积则是我们需要累加的面积。

    其中的测试数据计算过程如下:

    View Code
     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<algorithm>
     5 #include<string.h>
     6 using std::sort;
     7 using std::unique;
     8 const int N = 2222;
     9 struct node
    10 {
    11        double y,lx,rx;
    12        int s;
    13        bool operator <(const node &tmp)const{
    14            return y<tmp.y;
    15        }
    16 }line[N<<4];
    17 double X[N<<4],sum[N<<4];
    18 int cnt[N<<4];
    19 void update(int t,int l,int r,int L,int R,int val)
    20 {
    21     if(L<=l&&r<=R)
    22     {
    
    23         cnt[t]+=val;
    24         if(cnt[t])sum[t]=X[r+1]-X[l];
    25         else
    26            if(l==r)sum[t]=0;
    27            else sum[t]=sum[t<<1]+sum[t<<1|1];
    28         return ;
    29     }
    30     int m=(l+r)>>1;
    31     if(L<=m)update(t<<1,l,m,L,R,val);
    32     if(R>m)update(t<<1|1,m+1,r,L,R,val);
    33     if(cnt[t])sum[t]=X[r+1]-X[l];
    34         else
    35            if(l==r)sum[t]=0;
    36            else sum[t]=sum[t<<1]+sum[t<<1|1];
    37 }
    38 int Fin(double k,int len)
    39 {
    40     int l=0,r=len-1;
    41     while(l<r)
    42     {
    43          int m=(l+r)>>1;
    44          if(X[m]==k)return m;
    45          if(X[m]>k)r=m-1;
    46          else l=m+1;
    47     }
    48     return l;
    49 }
    50 int main()
    51 {
    52     int n,T=0;
    53     double x1,x2,y1,y2;
    54     while(scanf("%d",&n)&&n)
    55     {
    56         int top=0,i,j;
    57         for(i=0,j=0;i<n;i++,j+=2)
    58         {
    59             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
    60             X[top++]=x1,X[top++]=x2;
    61             line[j].y=y1,line[j].lx=x1,line[j].rx=x2,line[j].s=1;
    62             line[j+1].y=y2,line[j+1].lx=x1,line[j+1].rx=x2,line[j+1].s=-1;
    63         }
    64         sort(X,X+top);
    65         top=unique(X,X+top)-X;
    66         sort(line,line+j);
    67         int l,r;
    68         double answer=0;
    69         memset(cnt,0,sizeof(cnt));
    70         memset(sum,0,sizeof(sum));
    71         for(int i=0;i<j-1;i++)
    72         {
    73             l=Fin(line[i].lx,top);
    74             r=Fin(line[i].rx,top)-1;
    75             if(r>=l)update(1,0,top-1,l,r,line[i].s);
    76             answer+=sum[1]*(line[i+1].y-line[i].y);
    77         }
    78         printf("Test case #%d\nTotal explored area: %.2lf\n\n",++T,answer);
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    Mac 删除Openfire
    FMDB使用
    豆瓣restful api 状态和错误码
    豆瓣开放api
    常用文字配色方案
    电商网站参考
    HP后端跨域HEADER头
    PHP统计 图表实现方法
    PHP 全过程教程和测试网
    Ajax技术在购物车中的应用(PHP篇)
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2747032.html
Copyright © 2020-2023  润新知