您的位置:首页 > 其它

poj 1151 Atlantis

2011-02-26 14:32 274 查看
线段树的应用。

线段树求面积,比1177求周长方便

线段的覆盖长度乘以(e[i+1].x-e[i].x);

#include<iostream>
using namespace std;
#include<cstdlib>
#define maxn 210
struct node
{
int l,r,cover;
double sum,len;
};
struct edge
{
double st,ed,x;
bool inout;
};
edge e[maxn];
node st[maxn*4];
double index[maxn];
int intcmp(const void *a,const void *b)
{
return *(double *)a>*(double *)b?1:-1;
}
int edgecmp(const void *a,const void *b)
{
return ((edge *)a)->x>((edge *)b)->x?1:-1;
}
int getindex(double *source,int n,double key)
{
int left=0,right=n-1,mid;
while(left<=right)
{
mid=(left+right)/2;
if(source[mid]==key)
return mid;
else if(source[mid]>key)
right=mid-1;
else
left=mid+1;
}
}
void maketree(int l,int r,int i)
{
st[i].l=l,st[i].r=r;
st[i].cover=st[i].sum=0;
st[i].len=index[r]-index[l];
if(r-l>1)
{
int mid=(r+l)/2;
maketree(l,mid,i*2);
maketree(mid,r,i*2+1);
}
}
void getlen(int i)
{
if(st[i].cover>0)
st[i].sum=st[i].len;
else if(st[i].r-st[i].l>1)
st[i].sum=st[i*2].sum+st[i*2+1].sum;
else
st[i].sum=0;
}
void update(int l,int r,int i,int inout)
{
if(st[i].l==l&&st[i].r==r)
{
if(inout)
st[i].cover++;
else
st[i].cover--;
}
else
{
int mid=(st[i].l+st[i].r)/2;
if(l>=mid)
update(l,r,2*i+1,inout);
else if(r<=mid)
update(l,r,2*i,inout);
else
{
update(l,mid,2*i,inout);
update(mid,r,2*i+1,inout);
}
}
getlen(i);
}
int main()
{
int n,cnt,i,ca=0;
double x1,y1,x2,y2;
while(scanf("%d",&n),n)
{
ca++;
cnt=0;
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
index[2*i]=y1,index[2*i+1]=y2;
e[2*i].x=x1,e[2*i+1].x=x2;
e[2*i].inout=true,e[2*i+1].inout=false;
e[2*i].st=e[2*i+1].st=y1;
e[2*i].ed=e[2*i+1].ed=y2;
}
qsort(e,2*n,sizeof(e[0]),edgecmp);
qsort(index,2*n,sizeof(index[0]),intcmp);
for(i=1;i<=2*n-1;i++)
if(index[i]!=index[i-1])
index[cnt++]=index[i-1];
index[cnt++]=index[2*n-1];
maketree(0,cnt-1,1);
double ans=0;
for(i=0;i<2*n-1;i++)
{
if(e[i].inout)
update(getindex(index,cnt,e[i].st),getindex(index,cnt,e[i].ed),1,1);
else
update(getindex(index,cnt,e[i].st),getindex(index,cnt,e[i].ed),1,0);
ans+=st[1].sum*(e[i+1].x-e[i].x);
}
printf("Test case #%d/n",ca);
printf("Total explored area: %.2lf/n",ans);
printf("/n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: