poj1151 Atlantis

252K 16MS

 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct point
{
    double x;
    double y;
};
struct map
{
    point up;
    point down;
}m[1000];
struct node
{
    int L;
    int R;
    node *left;
    node *right;
    double len;//区间的长度
    int count;//被覆盖的层数
}tree[1000];
int nodecount;
bool cmp(double a,double b)
{
    return a<b;
}
void buildtree(node *p,int L,int R)
{
    p->L=L;
    p->R=R;
    p->len=0;
    p->count=0;
    if(L!=R)
    {
        nodecount++;
        p->left=tree+nodecount;
        nodecount++;
        p->right=tree+nodecount;
        buildtree(p->left,L,(L+R)/2);
        buildtree(p->right,(L+R)/2+1,R);
    }
}
double s[1000];//第i个区间上端距y[0]的距离
struct li
{
    double x;
    double y1;//上面
    double y2;//下面
    bool left;
}line[5000];//一共n*2条直线
int k;
int nline;
double y[1000];
bool cnp(li a,li b)
{
    return a.x<b.x;
}
double cal(int L,int R)//L号区间与R号区间距离
{
    return y[R]-y[L-1];
}
int binsearch(double x)
{
    int L=0;
    int R=k-1;
    int mid=(L+R)/2;
    while(y[mid]!=x)
    {
        if(x<y[mid])
        {
            R=mid-1;
            mid=(L+R)/2;
        }
        else
        {
            L=mid+1;
            mid=(L+R)/2;
        }
    }
    return mid+1;
}
void insert(node *p,int L,int R)
{
    if((p->L)==L&&(p->R)==R)
    {
        p->count++;
        p->len=cal(L,R);
        return;
    }
    int mid=(p->L+p->R)/2;
    if(R<=mid)
    {
        insert(p->left,L,R);
    }
    else if(L>=mid+1)
    {
        insert(p->right,L,R);
    }
    else
    {
        insert(p->left,L,mid);
        insert(p->right,mid+1,R);
    }
    if(p->count==0)
    {
        p->len=p->left->len+p->right->len;
    }
}
void dele(node *p,int L,int R)
{
    if(p->L==L&&p->R==R)
    {
        p->count--;
        if(p->count==0)
        {
            if(p->L==p->R)
            {
                p->len=0;
            }
            else
            {
                p->len=p->left->len+p->right->len;
            }
        }
        return;
    }
    int mid=(p->L+p->R)/2;
    if(R<=mid)
    {
        dele(p->left,L,R);
    }
    else if(L>=mid+1)
    {
        dele(p->right,L,R);
    }
    else
    {
        dele(p->left,L,mid);
        dele(p->right,mid+1,R);
    }
    if(p->count==0)
    {
        p->len=p->left->len+p->right->len;
    }
}
//bool operator==(const li &a,const li &b)
//{
//    return a.x==b.x;
//}
int main()
{
    int total=1;
    int n;
    int i;
    k=0;
    while(scanf("%d",&n),n)
    {
        nline=0;
        printf("Test case #%d\n",total++);
        for(i=0;i<n;i++)
        {
            scanf("%lf %lf %lf %lf",&m[i].up.x,&m[i].up.y,&m[i].down.x,&m[i].down.y);
            y[k++]=m[i].up.y;
            y[k++]=m[i].down.y;
            line[nline].x=m[i].up.x;
            line[nline].left=true;
            line[nline].y1=m[i].up.y;
            line[nline].y2=m[i].down.y;
            nline++;
            line[nline].x=m[i].down.x;
            line[nline].left=false;
            line[nline].y1=m[i].up.y;
            line[nline].y2=m[i].down.y;
            nline++;
        }
        sort(y,y+k,cmp);//从小到大排序y[0],,,,,y[k-1]...第i个区间为y[i-1]-y[i],共有1,2,,,k-1号区间
        k=unique(y,y+k)-y;
        nodecount=0;
        buildtree(tree,1,k-1);
        sort(line,line+nline,cnp);
        //nline=unique(line,line+nline)-line;
        double res=0;
        int L,R;
        for(i=0;i<nline-1;i++)
        {
            if(line[i].left==true)
            {
                if(line[i].y1>line[i].y2)
                {
                    R=binsearch(line[i].y1)-1;
                    L=binsearch(line[i].y2);
                    insert(tree,L,R);
                }
                else
                {
                    R=binsearch(line[i].y2)-1;
                    L=binsearch(line[i].y1);
                    insert(tree,L,R);
                }
            }
            else
            {
                if(line[i].y1>line[i].y2)
                {
                    R=binsearch(line[i].y1)-1;
                    L=binsearch(line[i].y2);
                    dele(tree,L,R);
                }
                else
                {
                    R=binsearch(line[i].y2)-1;
                    L=binsearch(line[i].y1);
                    dele(tree,L,R);
                }
            }
            res+=tree[0].len*(line[i+1].x-line[i].x);
        }
        printf("Total explored area: %.2f\n\n",res);
    }
    return 0;
}

posted @ 2012-07-19 09:20  willzhang  阅读(134)  评论(0编辑  收藏  举报