ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

POJ 1151 Atlantis

2019-08-10 15:01:23  阅读:297  来源: 互联网

标签:Atlantis rr int ll 1151 len sh POJ 矩形


线段树+扫描线

矩形面积并

之前写过矩形周长并

 

还是跟矩形周长并一样,将每一个矩形的横边和竖边处理出来

用竖边将整个平面分成若干个区间

用线段树维护这些区间被覆盖的长度

再用一条扫描线不断从下往上扫描,扫描横边

当扫描到一个矩形的下边时,将这一段区间在线段树上覆盖掉,更新信息

当扫描到一个矩形的上边时,将这一段区间的覆盖去掉即可

那么只有统计答案时与矩形周长并不同

答案就是当前整个区间被覆盖的长度*两次扫描线的高度之差

#include <iostream>
#include <algorithm>
#include <map>
#include <cstdio>
#define inf (int)1e9
using namespace std;
int n,w,last,tot,k;
double c[10000],ans;
double s[10000];
map <double,int> id;
struct node
{
    double a,b,c,d;
}p[5100];
struct tree
{
    int l,r,sum;
    double len;
}sh[100000];
struct edge
{
    int l,r,kind;
    double num;
}a[11000];
bool cmp(edge a,edge b)
{
    return (a.num<b.num || (a.num==b.num && a.kind>b.kind));
}
void pushup(int x)
{
    if (sh[x].sum>0)
      sh[x].len=c[sh[x].r+1]-c[sh[x].l];//完全覆盖
    else
    if (sh[x].l==sh[x].r)
      sh[x].len=0;//叶子结点
    else
      sh[x].len=sh[x+x].len+sh[x+x+1].len;//一般情况
}
void build(int x,int ll,int rr)
{
    sh[x].l=ll;
    sh[x].r=rr;
    sh[x].sum=0;
    sh[x].len=0;
    if (ll==rr)
      return;
    int mid;
    mid=(ll+rr)>>1;
    build(x+x,ll,mid);
    build(x+x+1,mid+1,rr);
}
void change(int x,int ll,int rr,int v)
{
    if (sh[x].l>=ll && sh[x].r<=rr)
    {
        sh[x].sum+=v;
        pushup(x);
        return;
    }
    int mid;
    mid=(sh[x].l+sh[x].r)>>1;
    if (ll<=mid)
      change(x+x,ll,rr,v);
    if (rr>mid)
      change(x+x+1,ll,rr,v);
    pushup(x);
}
int main()
{
    while (1)
    {
        tot++;
        scanf("%d",&n);
        if (n==0)
          break;
        for (int i=1;i<=n;i++)
          scanf("%lf%lf%lf%lf",&p[i].a,&p[i].b,&p[i].c,&p[i].d);
        k=0;
        for (int i=1;i<=n;i++)
        {
            k++;
            s[k]=p[i].a;
            k++;
            s[k]=p[i].c;
        }
        sort(s+1,s+1+k);
        int m=unique(s+1,s+1+k)-s-1;
        for (int i=1;i<=m;i++)
          id[s[i]]=i,c[i]=s[i];
         w=0;
        for (int i=1;i<=n;i++)//处理扫描线
        {
            w++;
            a[w].l=id[p[i].a];a[w].r=id[p[i].c];
            a[w].num=p[i].b;a[w].kind=1;
            w++;
            a[w].l=id[p[i].a];a[w].r=id[p[i].c];
            a[w].num=p[i].d;a[w].kind=-1;
        }
        build(1,0,m+1);
        sort(a+1,a+1+w,cmp);
        ans=0;
        for (int i=1;i<=w;i++)
        {
            change(1,a[i].l,a[i].r-1,a[i].kind);
            if (i==w)
              break;
            ans+=(a[i+1].num-a[i].num)*sh[1].len;//统计答案
        }
        printf("Test case #%d\n",tot);
        printf("Total explored area: %.2f\n\n",ans);
    }
}

 

标签:Atlantis,rr,int,ll,1151,len,sh,POJ,矩形
来源: https://www.cnblogs.com/huangchenyan/p/11331648.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有