zoukankan      html  css  js  c++  java
  • ZOJ 3521 Fairy Wars oj错误题目,计算几何,尺取法,排序二叉树,并查集 难度:2

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3521 

    ATTENTION:如果用long long 减小误差,这道题只能用%lld读入

    首先需要判断哪些点是相互挨着的,这样比直接维护哪些集合是冰冻住的简单

    按照x为主,y为辅排序,在数组上尺取,当head与tail的x坐标相差大于l/2则把head向后移动直到x坐标满足条件,

    那么对于head到tail,现在的问题就只剩下检测出哪些点之间y间距小于l/2,把它们都按照pair<y,id>加入set,那么离tail最近的两个点的y坐标就是离tail最近的,如果其中某个点满足间距小于l/2,那么就把tail和这个点放在一个并查集里,(其他的点如果满足条件,会和这两个点在一个并查集里)

    最后统计一下哪些并查集是被冰冻住的,以及这些并查集中有多少点即可

    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> P;
    const int maxn=5e4+3;
    int n;
    ll r,l;
    P pnt[maxn],o;
    int par[maxn];
    bool in[maxn];
    
    ll dis(P a,P b){return (a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second);}
    
    int fnd(int i){return(par[i]==i?i:(par[i]=fnd(par[i])));}
    bool same(int a,int b){return fnd(a)==fnd(b);}
    void unite(int a,int b){
            if(!same(a,b)){
                    par[par[b]]=par[a];
            }
    }
    
    
    void solve(){
            set<P> st;
            int head=0;
            for(int tail=0;tail<n;tail++){
                    while(2*abs(pnt[tail].first-pnt[head].first)>l){
                            st.erase(P(pnt[head].second,head));
                            head++;
                    }
                    set<P>::iterator it = st.insert(P(pnt[tail].second,tail)).first;
                    if(it!=st.begin()){
                            it--;
    //printf("s:%lld %lld
    ",it->first,pnt[tail].second);
                            if(2*abs(pnt[tail].second-it->first)<=l){
                                    unite(tail,it->second);
                            }
                            it++;
                    }
    
                    it++;
                    if(it!=st.end()){
                            if(2*abs(it->first-pnt[tail].second)<=l){
                                    unite(tail,it->second);
                            }
                    }
            }
    }
    
    void output(){
            int ans=0;
            for(int i=0;i<n;i++){
                    if(dis(pnt[i],o)<=r*r){
                            if(!in[fnd(i)]){
                                    in[par[i]]=true;
                            }
                    }
            }
            for(int i=0;i<n;i++){
                    if(in[fnd(i)]){
                            ans++;
                    }
            }
    
            printf("%d
    ",ans);
    }
    int main(){
            while(scanf("%d%lld%lld",&n,&r,&l)==3){
                    memset(in,0,sizeof(in));
                    for(int i=0;i<n;i++){
                            scanf("%lld%lld",&(pnt[i].first),&(pnt[i].second));
                            par[i]=i;
                    }
                    scanf("%lld%lld",&(o.first),&(o.second));
    
                    sort(pnt,pnt+n);
    
                    solve();
                    output();
            }
            return 0;
    }
    

      

  • 相关阅读:
    VS 2008潜在强大的功能:提取EXE文件中的ICO等资源
    园友们注意:淘宝网上QQ会员 4钻 3元 等都为骗子行为
    Comet Async Process Request Handler
    WCF(Sender) to MSMQ to WCF(Receiver)
    ASP.NET Web Form GridView DetailsView Query Edit
    WCF NetTcp AsyncQueue Service
    Xml CDATA 序列化
    Sync Invoke Remoting Async Invoke
    .Net 4.0 Remoting ConcurrentQueue
    Socket Async Receive Data to LinkedList Buffer (telnet proxy server)
  • 原文地址:https://www.cnblogs.com/xuesu/p/4296912.html
Copyright © 2011-2022 走看看