zoukankan      html  css  js  c++  java
  • POJ 3470 Walls(线段树+扫描线)

    【题目链接】 http://poj.org/problem?id=3470

    【题目大意】

      给出几面墙,均垂直于x轴或者y轴,给出一些鸟的位置(二维坐标点),
      鸟只会垂直x轴或者y轴飞行,并且会撞上最近的墙,问每面墙最后会有几只鸟撞上去。

    【题解】

      我们将所有的二维坐标离散,对xy方向分别进行扫描线,
      以y轴方向为例,我们先从y最小的线开始扫,
      如果是墙,那么在线段树中更新其在x轴上的分布位置
      如果是鸟的坐标,那么在线段树中查找其位置,更新其答案。
      之后从y最大的开始反向扫描,更新,x方向也同理。

    【代码】

    #include <cstdio>
    #include <algorithm> 
    #include <cstring>
    #include <climits>
    using namespace std;
    const int N=50010;
    int n,m,wall,tot,dis[N],v[N],w[N],T[10*N],*arr;
    int x[3*N],y[3*N],ry[3*N],rx[3*N],r[3*N],xs[3*N],ys[3*N],px[3*N],py[3*N];
    bool cmp(int a,int b){return arr[a]<arr[b];}
    void compress(int *x,int *r,int n,int *a,int *mp){
        for(int i=0;i<n;i++)r[i]=i; 
        arr=x; sort(r,r+n,cmp);
        int m=-1; a[r[0]]=++m; mp[m]=x[r[0]];
        for(int i=1;i<n;i++){
            int cur=r[i],lst=r[i-1];
            if(x[cur]==x[lst])a[cur]=m;
            else a[cur]=++m,mp[m]=x[cur];
        }
    }
    int query(int q,int x,int l,int r){
        if(T[x]!=-2)return T[x];
        int mid=(l+r)>>1;
        if(q<mid)return query(q,x<<1|1,l,mid);
        return query(q,x+1<<1,mid,r);
    }
    void update(int a,int b,int x,int l,int r,int val){
        if(r<=a||b<=l)return;
        else if(a<=l&&r<=b)T[x]=val;
        else{
            if(T[x]!=-2){
                T[x+1<<1]=T[x<<1|1]=T[x];
                T[x]=-2;
            }int mid=(l+r)>>1;
            update(a,b,x<<1|1,l,mid,val); 
            update(a,b,x+1<<1,mid,r,val);
        }
    }
    void scan(int k,int *ys,int *xs,int *py,int W){
        if(k<wall){
            int _k=k^1;
            if(xs[_k]>=xs[k])update(xs[k],xs[_k]+1,0,0,W,k/2); 
        }else{
            int t=query(xs[k],0,0,W);
            if(~t){
                int d=min(abs(py[ys[k]]-py[ys[t*2]]),abs(py[ys[k]]-py[ys[t*2+1]]));
                k-=wall; if(d<dis[k])dis[k]=d,v[k]=t;
            }
        }
    }
    void fly(int *ry,int *ys,int *xs,int *py,int W){
        T[0]=-1; for(int i=0;i<tot;i++)scan(ry[i],ys,xs,py,W);
        T[0]=-1; for(int i=tot-1;i>=0;i--)scan(ry[i],ys,xs,py,W); 
    }
    int main(){
        scanf("%d%d",&n,&m);
        wall=2*n; tot=wall+m;
        for(int i=0;i<tot;i++)scanf("%d%d",x+i,y+i);
        compress(x,rx,tot,xs,px);
        compress(y,ry,tot,ys,py);
        fill(dis,dis+m,INT_MAX);memset(w,0,n);
        fly(ry,ys,xs,py,xs[rx[tot-1]]+1);
        fly(rx,xs,ys,px,ys[ry[tot-1]]+1);
        for(int i=0;i<m;i++)++w[v[i]];
        for(int i=0;i<n;i++)printf("%d
    ",w[i]);
        return 0;
    }
  • 相关阅读:
    Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
    Appcan——Box
    基于SSH框架的网上商城的质量属性
    框架的选择
    软件体系结构的认识
    Cocos2d-x项目创建方式
    一、设计模式简介
    数组与字符串四(例子、使用(2))
    数组与字符串三(Cocos2d-x 3.x _Array容器)
    数组与字符串二(例子、使用)
  • 原文地址:https://www.cnblogs.com/forever97/p/poj3470.html
Copyright © 2011-2022 走看看