POJH 1151 Atlantis

Scan line segment tree +

And a rectangular area

Written before the rectangular perimeter and

 

And the same or with a rectangular perimeter, each side of a rectangular cross-out processing and the vertical edge

The whole edge with a vertical plane into a plurality of sections

The length of the maintenance interval is covered by the segment tree

A scan line and then continues to scan from the bottom up, scan lateral edge

When scanning to a lower rectangular section of these sections of the segment tree overwritten, update information

When scanning the upper side of a rectangle, a period covering these sections can be removed

Then only when statistics rectangular perimeter and different answers

The answer is the current difference in height between the entire range covered by the two scan line length *

#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);
    }
}

 

Guess you like

Origin www.cnblogs.com/huangchenyan/p/11331648.html