Atlantis

题述《 http://poj.org/problem?id=1151

#include<stdio.h>
#include<algorithm>
using namespace std;
struct line
{
   double x1,y1,y2;
   int isl;
}verl[257];
struct node
{
   int l,r;
   double len;
   int covn;
};
node itree[1257];
double y[257];
bool operator < (const line &a,const line &b)
{
   return a.x1<b.x1;
}
void ibuild(int id,int l,int r)
{
   itree[id].l=l;
   itree[id].r=r;
   itree[id].len=0;
   itree[id].covn=0;
   if(l==r)
      return ;
   ibuild(id*2+1,l,(l+r)/2);
   ibuild(id*2+2,(l+r)/2+1,r);
}
void iinsert(int id,int l,int r)
{
   if(itree[id].l==l&&itree[id].r==r)
   {
      itree[id].len=y[r+1]-y[l];
      ++itree[id].covn;
      return ;
   }
   if(r<(itree[id].l+itree[id].r)/2+1)
      iinsert(id*2+1,l,r);
   else if(l>(itree[id].l+itree[id].r)/2)
      iinsert(id*2+2,l,r);
   else
   {
      iinsert(id*2+1,l,(itree[id].l+itree[id].r)/2);
      iinsert(id*2+2,(itree[id].l+itree[id].r)/2+1,r);
   }
   if(itree[id].covn==0)
      itree[id].len=itree[id*2+1].len+itree[id*2+2].len;
}
void idelete(int id,int l,int r)
{
   if(itree[id].l==l&&itree[id].r==r)
   {
      --itree[id].covn;
      if(itree[id].covn==0)
      {
         if(itree[id].l==itree[id].r)
            itree[id].len=0;
         else
            itree[id].len=itree[id*2+1].len+itree[id*2+2].len;
      }
      return ;
   }
   if(r<(itree[id].l+itree[id].r)/2+1)
      idelete(id*2+1,l,r);
   else if(l>(itree[id].l+itree[id].r)/2)
      idelete(id*2+2,l,r);
   else
   {
      idelete(id*2+1,l,(itree[id].l+itree[id].r)/2);
      idelete(id*2+2,(itree[id].l+itree[id].r)/2+1,r);
   }
   if(itree[id].covn==0)
      itree[id].len=itree[id*2+1].len+itree[id*2+2].len;
}
int binarys(double *y,int yl,double v)
{
   int l,r,m;
   int i,j,k;
   l=0;r=yl-1;
   while(l<yl)
   {
      m=(l+r)/2;
      if(y[m]>v)
         r=m-1;
      else if(y[m]<v)
         l=m+1;
      else
         return m;
   }
   return -1;
}
int main()
{
   int n;
   double x1,x2,y1,y2;
   double res=0;
   int l,r;
   int i,j,k;
   int ii;
   k=0;
   while(~scanf("%d",&n)&&n)
   {
      i=-1;
      do
      {
         scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
         y[++i]=y1;
         verl[i].x1=x1;verl[i].y1=y1;verl[i].y2=y2;verl[i].isl=1;
         y[++i]=y2;
         verl[i].x1=x2;verl[i].y1=y1;verl[i].y2=y2;verl[i].isl=0;
      }while(--n);
      sort(y,y+i+1);
      ii=unique(y,y+i+1)-y;
      ibuild(0,0,ii-1-1);
      sort(verl,verl+i+1);
      res=0;
      for(j=i,i=0;i<j;++i)
      {
         l=binarys(y,ii,verl[i].y1);
         r=binarys(y,ii,verl[i].y2);
         if(verl[i].isl)
            iinsert(0,l,r-1);
         else
            idelete(0,l,r-1);
         res+=itree[0].len*(verl[i+1].x1-verl[i].x1);
      }
      printf("Test case #%d\nTotal explored area: %.2f\n\n",++k,res);
   }
   return 0;
}

规定矩形的位置用矩形的左下角和右上角坐标表示,给定矩形,要求给出被矩形覆盖的面积并。想象在坐标系里的 1 根扫描线,向 1 个方向扫描的时候每碰到矩形的 1 条边即停下(矩形坐标的 x 点),计算这条边和上条边间的面积(两边 x 点之差 * 更新线段树统计的区间)。

算法《 https://wswmsword.github.io/2019/06/06/线段树/
算法《折半查找》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值