poj1389 Area of S…

来源:互联网 发布:大津算法 matlab 编辑:程序博客网 时间:2024/05/22 11:56
这个是线段树的经典题目了。
求n个矩形的面积并。
   解法:把y坐标离散化,输入的矩形转换成两条平行于y轴的线(然后按x坐标排序)分别为入边和出边,然后对y轴建立线段树,依次插入线段。这个做法文字不好解释,具体的看代码吧。
#include
#include
#include
#include
using namespace std;
const int maxn=1101;
int ans;
struct
{
    int l,r,x;
    int y1,y2;
    bool ture;
    int count;
}tr[10000];

struct data
{
    int x,y1,y2,count;
    bool operator <(constdata &xx) const
    {
       return(x
    }
}d[maxn*2];
int y[maxn*2];

int maketree(int t,int l,int r)
{
    tr[t].l=l;
    tr[t].r=r;
    tr[t].y1=y[l];
    tr[t].y2=y[r];
    tr[t].ture=1;
    tr[t].count=0;
    if(l+1==r)
    return(0);
    int mid=(l+r)/2;
   maketree(t*2,l,mid);
   maketree(t*2+1,mid,r);
}

int pushdown(int t)
{
    tr[t*2].x=tr[t].x;
   tr[t*2].count=tr[t].count;
   tr[t*2+1].x=tr[t].x;
   tr[t*2+1].count=tr[t].count;
}

int insert(int t,int y1,int y2,data &d)
{
   if(tr[t].y1==y1&&tr[t].y2==y2)
    {
       if(tr[t].ture)
       {
          if(tr[t].count>0)
           {
              int txt=y2-y1;
              ans+=txt*(d.x-tr[t].x);
           }
          tr[t].count+=d.count;
          tr[t].x=d.x;
          return(0);
       }
    }
    if(tr[t].ture)
    pushdown(t);
    tr[t].ture=0;
    intmid=(tr[t].l+tr[t].r)/2;
    mid=y[mid];
          if(mid<=y1)
          insert(t*2+1,y1,y2,d);
           elseif(y2<=mid)
          insert(t*2,y1,y2,d);
           else
           {
              insert(t*2,y1,mid,d);
              insert(t*2+1,mid,y2,d);
           }
}



int main()
{
    int n;
    while(1)
    {
       int x1,x2,y1,y2;
       scanf("%d %d %d%d",&x1,&y1,&x2,&y2);
      if(x1==-1&&y1==-1&&x2==-1&&y2==-1)
       break;
       d[1].x=x1;
       d[1].y1=y1;
       d[1].y2=y2;
       d[2].x=x2;
       d[2].y1=y1;
       d[2].y2=y2;
       d[1].count=1;
       d[2].count=-1;
       y[1]=y1;
       y[2]=y2;
       for(int i=2;;i++)
       {
           scanf("%d%d %d %d",&x1,&y1,&x2,&y2);
           intnow=2*i-1,next=now+1;
          d[now].x=x1;
          d[now].y1=y1;
          d[now].y2=y2;
          d[next].x=x2;
          d[next].y1=y1;
          d[next].y2=y2;
          d[now].count=1;
          d[next].count=-1;
          y[now]=y1;
          y[next]=y2;
          if(x1==-1&&y1==-1&&x2==-1&&y2==-1)
           {
              n=i-1;
              break;
           }
       }
       sort(y+1,y+2*n+1);
       sort(d+1,d+2*n+1);
       maketree(1,1,2*n);
       ans=0;
       for(int i=1;i<=2*n;i++)
       {
          insert(1,d[i].y1,d[i].y2,d[i]);
       }
       printf("%d\n",ans);
    }
    return 0;
}

原创粉丝点击