hdu 1542 Atlantis

面积交是在面积并上修改的,一开始直接把fun里面的if( tree[i].cover >= 1)判断条件改成了 if( tree[i].cover >= 2 ),交了N遍WA,后来发现有种情况没有考虑,如果第一次覆盖,第二次覆盖是第一次的父节点。尝试标记父节点的时候,也标记子树,但发现会有冲突,后来参考了网上牛人的代码,在tree里面增加一个once用来记录只覆盖了一次的节点,然后对fun加以相应的修改,AC了。


#include<iostream>  
#include<string.h>  
using namespace std;  
struct node 
{  
   int l; 
   int r; 
   int cover; 
   double len; 
}; 
node tree[2000]; 
double yy[250]; 
int n,len;
struct Line 
{ 
    double y_down; 
    double y_up; 
    double x; 
    int cover; 
}; 
Line line[250];
int cmp(Line a,Line b) 
{   
    return a.x<b.x;
} 
int find(double x) 
{ 
    int l=0,r=len,mid;      
    while(l<=r) 
    {         
      mid=(l+r)/2;        
      if(yy[mid]==x)              
        return mid;          
      if(yy[mid]<x)             
        l=mid+1;          
      else              
        r=mid-1;    
    }      
    return l; 
} 
void build(int i,int l,int r) 
{ 
    tree[i].l=l; 
    tree[i].r=r; 
    tree[i].cover=0; 
    tree[i].len=0; 
    if(l+1==r) 
      return; 
    int mid=(l+r)/2;
    build(2*i,l,mid); 
    build(2*i+1,mid,r); 
}
void fun(int i) 
{ 
   if(tree[i].cover) 
      tree[i].len=yy[tree[i].r]-yy[tree[i].l];   
   else if(tree[i].l+1==tree[i].r)         
      tree[i].len=0; 
   else          
      tree[i].len=tree[2*i].len+tree[2*i+1].len;
} 
void updata(int i,int l,int r,int cover) 
{
   if(tree[i].l>r || tree[i].r<l) 
       return; 
   if(tree[i].l>=l && tree[i].r<=r) 
   {
       tree[i].cover+=cover; 
       fun(i); 
       return; 
   } 
   updata(2*i,l,r,cover); 
   updata(2*i+1,l,r,cover);
   fun(i); 
} 
int main() 
{
    double x1,y1,x2,y2;
    int i,m,a,b,cas=1;
    while(scanf("%d",&n)==1 && n) 
    { 
       m=0; 
       for(i=0;i<n;i++) 
       { 
          scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 
          yy[m]=y1;              
          line[m].cover=1;            
          line[m].x=x1;
          line[m].y_down=y1;          
          line[m++].y_up=y2;
          yy[m]=y2;
          line[m].cover=-1;
          line[m].x=x2;
          line[m].y_down=y1;
          line[m++].y_up=y2;
       }
       sort(yy,yy+m);
       len=1;
       for(i=1;i<m;i++)
       {
          if(yy[i-1]!=yy[i])
            yy[len++]=yy[i];
       }
       len--;
       build(1,0,len);
       sort(line,line+m,cmp);
       double ans=0;
       printf("Test case #%d\n",cas++);
       for(i=0;i<m-1;i++)
       {
          a=find(line[i].y_down);
          b=find(line[i].y_up);
          updata(1,a,b,line[i].cover);
          ans+=tree[1].len*(line[i+1].x-line[i].x); 
       }
       printf("Total explored area: %0.2lf\n\n",ans);
    }
  return 0;
  }




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值