POJ-1151-Atlantis

378 篇文章 0 订阅

学习到线段树,然后有些题要求覆盖面积,据说用扫描线做,这算是我这类题的第一个吧

参考了好多资料,最后看的http://blog.csdn.net/youngyangyang04/article/details/7787693

勉强懂了些吧,最开始一直没理解到计算长度的时候t[index].l+1==t[index].r这里赋为0,后来想通了,原来是当val<=0的时候要删除当前边结点。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=311;
struct node
{
    double x;
    double y1;
    double y2;
    int flag;
    bool operator <(const node &a)const
    {
	return x<a.x;
    }
}p[maxn];
struct Tree
{
    int l;
    int r;
    double ly;
    double ry;
    double len;
    int val;
}t[maxn*2];
int n;
double py[maxn];
void Build(int L,int R,int index)
{
    t[index].l=L;
    t[index].r=R;
    t[index].ly=py[L];
    t[index].ry=py[R];
    t[index].len=t[index].val=0;
    if(L==R-1)
	return;
    int mid=(L+R)>>1;
    Build(L,mid,index<<1);
    Build(mid,R,index<<1|1);
}
void Callen(int index)
{
    if(t[index].val>0)
	t[index].len=t[index].ry-t[index].ly;
    else if(t[index].l+1==t[index].r)
	t[index].len=0;
    else
	t[index].len=t[index<<1].len+t[index<<1|1].len;
}
void Update(double y1,double y2,int val,int index)
{
    if(t[index].ly==y1&&t[index].ry==y2)
    {
	t[index].val+=val;
	Callen(index);
	return;
    }
    if(y2<=t[index<<1].ry)
	Update(y1,y2,val,index<<1);
    else if(y1>=t[index<<1|1].ly)
	Update(y1,y2,val,index<<1|1);
    else
    {
	Update(y1,t[index<<1].ry,val,index<<1);
	Update(t[index<<1|1].ly,y2,val,index<<1|1);
    }
    Callen(index);
}
int main()
{
    int cas=1;
    while(scanf("%d",&n)&&n)
    {
	int count=1;
	for(int i=1;i<=n;i++)
	{
	    double x1,y1,x2,y2;
	    scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
	    p[count].x=x1;
	    p[count].y1=y1;
	    p[count].y2=y2;
	    p[count].flag=1;
	    py[count++]=y1;
	    p[count].x=x2;
	    p[count].y1=y1;
	    p[count].y2=y2;
	    p[count].flag=-1;
	    py[count++]=y2;
	}
	count--;
	sort(p+1,p+count+1);
	sort(py+1,py+count+1);
	Build(1,count,1);
	Update(p[1].y1,p[1].y2,p[1].flag,1);
	double ans=0;
	for(int i=2;i<=count;i++)
	{
	    ans+=t[1].len*(p[i].x-p[i-1].x);
	    Update(p[i].y1,p[i].y2,p[i].flag,1);
	}
	printf("Test case #%d\n",cas++);
	printf("Total explored area: %.2lf\n\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值