• hdu 1542


    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542

    题意:

    求所给矩形的覆盖面积

    题解:

    利用扫描线的思想,先将坐标离散化,之后以y轴分成多个矩形求解,可以让下边界+1上边界-1

    问题就转化为了:求区间中有多少个非0数,要求支持区间+1 -1操作

    我们可以通过维护区间最小值以及最小值的个数来完成这件事情

    代码:

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include <iostream>
    #define maxn 5000
    #define INF 59999999
    #define eps 1e-6
    #define mid (h+t)/2
    using namespace std;
    struct re 
    {
        double a;int b;
    }a[maxn],b[maxn];
    struct ree
    {
        int h,t,x,lazy;
        double sum,tot;
    }p[maxn*4];
    double c[maxn];
    int a1[maxn];
    bool cmp(re x,re y)
    {
      if (x.a<y.a) return(true); else return(false);
    }
    void build(int x,int h,int t)
    {
        p[x].h=h; p[x].t=t; p[x].x=0;
        if (h==t) 
        {
          p[x].sum=p[x].tot=c[h+1]-c[h];
          return;
        }
        build(x*2,h,mid);
        build(x*2+1,mid+1,t);
        p[x].sum=p[x].tot=p[x*2].sum+p[x*2+1].sum;
    }
    void updata(int x)
    {
            p[x].x=min(p[x*2].x,p[x*2+1].x);
            if (p[x*2].x==p[x*2+1].x)
            {
                p[x].sum=p[x*2].sum+p[x*2+1].sum;
            }
            else
            {
                if (p[x*2].x<p[x*2+1].x) p[x].sum=p[x*2].sum;
                else p[x].sum=p[x*2+1].sum;
            }
            return;
    }
    void down(int x)
    {
        if (p[x].lazy==0) return;
        p[x].x+=p[x].lazy;
        p[x*2].lazy+=p[x].lazy;
        p[x*2+1].lazy+=p[x].lazy;
        p[x].lazy=0;
    }
    void insert(int x,int h,int t,int sum)
    {
        down(x);
        if (p[x].h>t|| p[x].t<h) return;
        if (h<=p[x].h &&p[x].t<=t)
        {
          p[x].lazy+=sum; down(x); return;
        }
        insert(x*2,h,t,sum); insert(x*2+1,h,t,sum);
        updata(x);
    }
    double query(int x,int h,int t)
    {
        down(x);
        if (p[x].h>t||p[x].t<h) return(0);
        if (h<=p[x].t && p[x].t<=t)
        {
            if (p[x].x==0) return(p[x].tot-p[x].sum); else return(p[x].tot);
        }
        return(query(x*2,h,t)+query(x*2+1,h,t));
    }
    int main()
    {int n,o=0;
    while (cin>>n&&n!=0)
    {
        o++;
      memset(p,0,sizeof(p));
      for (int i=1;i<=2*n;i++) a[i].b=i,b[i].b=i;
      for (int i=1;i<=n;i++)
      {
          cin>>a[2*i-1].a>>b[2*i-1].a>>a[2*i].a>>b[2*i].a;
      }
      sort(a+1,a+1+2*n,cmp);
      sort(b+1,b+1+2*n,cmp); 
      int ll=0; a[0].a=INF;
      for (int i=1;i<=2*n;i++)
      {
          if (abs(a[i].a-a[i-1].a)>eps) ll++;
          a1[a[i].b]=ll;
          c[ll]=a[i].a;
      }
      double ans=0;
        build(1,1,ll-1);
      for (int i=1;i<2*n;i++)
      {
          int pp,tmp=b[i].b;
          if (tmp%2==1) pp=1 ;else pp=-1;
        insert(1,a1[(tmp+1)/2*2-1],a1[(tmp+1)/2*2]-1,pp);
        ans+=(b[i+1].a-b[i].a)*query(1,1,ll-1); 
      }
      cout<<"Test case #"<<o<<endl<<"Total explored area: " ;
      printf("%.2f
    
    ",ans);
      }
    }
    View Code
  • 相关阅读:
    mysql中bigint、int、mediumint、smallint 和 tinyint的取值范围
    centos6.5下安装samba服务器与配置
    centos 6.5 安装图形界面【转】
    Linux 下添加用户,修改权限
    Linux下自动调整时间和时区与Internet时间同步
    C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)
    Unity脚步之NetworkBehaviour下前进、后退、左右转向的简单移动
    Token 在 Ajax 请求头中,服务端过滤器跨域问题
    【游戏】【暗黑2】重置属性点和技能点
    ASCII
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8387182.html
Copyright © 2020-2023  润新知