zoukankan      html  css  js  c++  java
  • 101485 F

    历史遗留问题
    三维球面模板题叭算个。
    有个性质挺好玩的。
    飞机肯定是先飞一段陆地,再飞一段水,这样子。所以只有求一下所有交点按对起始点距离排序即可。
    暂时还没理解两个弧线是怎么求交点的,抄的别人的板子。
    好像我三维几何除了傻逼最小球覆盖这种其他的都没怎么写过。。。
    教练模式真爽啊我草我要爽死了(bushi)

    #include <bits/stdc++.h>
    using namespace std;
    typedef double db;
    const db eps=1e-6;
    const db pi=acos(-1);
    const db R=6370;
    int sign(db k){
        if (k>eps) return 1; else if (k<-eps) return -1; return 0;
    }
    int cmp(db k1,db k2){return sign(k1-k2);}
    struct P3{
        db x,y,z;
        P3 operator + (P3 k1){return (P3){x+k1.x,y+k1.y,z+k1.z};}
        P3 operator - (P3 k1){return (P3){x-k1.x,y-k1.y,z-k1.z};}
        P3 operator * (db k1){return (P3){x*k1,y*k1,z*k1};}
        P3 operator / (db k1){return (P3){x/k1,y/k1,z/k1};}
        db abs2(){return x*x+y*y+z*z;}
        db abs(){return sqrt(x*x+y*y+z*z);}
        P3 unit(){return (*this)/abs();}
        int operator < (const P3 k1) const{
            if (cmp(x,k1.x)!=0) return x<k1.x;
            if (cmp(y,k1.y)!=0) return y<k1.y;
            return cmp(z,k1.z)==-1;
        }
        int operator == (const P3 k1){
            return cmp(x,k1.x)==0&&cmp(y,k1.y)==0&&cmp(z,k1.z)==0;
        }
        void scan(){
            double k1,k2,k3; scanf("%lf%lf%lf",&k1,&k2,&k3);
            x=k1; y=k2; z=k3;
        }
    };
    P3 cross(P3 k1,P3 k2){return (P3){k1.y*k2.z-k1.z*k2.y,k1.z*k2.x-k1.x*k2.z,k1.x*k2.y-k1.y*k2.x};}
    db dot(P3 k1,P3 k2){return k1.x*k2.x+k1.y*k2.y+k1.z*k2.z;}
    db Acos(db x){return acos(max(-(db)1,min(x,(db)1)));}
    // 球面距离 , 圆心原点 , 半径 1
    db Odist(P3 a,P3 b){db r=Acos(dot(a,b)); return r;}
    P3 getp(db x,db y){
        x=x*pi/180;y=y*pi/180;
        return P3{cos(x)*cos(y),cos(x)*sin(y),sin(x)};
    }
    bool checkSS(P3 a,P3 b,P3 c,P3 d,P3 &e){//from pku shanquan2
        e=cross(cross(a,b),cross(c,d));//弧线的交点
        if(sign(e.abs())==0)return 0;
        e=e.unit();
        if(cmp(Odist(a,e)+Odist(e,b),Odist(a,b))==0&&cmp(Odist(c,e)+Odist(e,d),Odist(c,d))==0)return 1;
        e=(P3){0,0,0}-e;
        if(cmp(Odist(a,e)+Odist(e,b),Odist(a,b))==0&&cmp(Odist(c,e)+Odist(e,d),Odist(c,d))==0)return 1;
        return 0;
    }
    P3 a[33][33],q[996];
    int c,m,sz[33];db x,y;
    int main(){
        scanf("%d",&c);
        for(int i=0;i<c;i++){
            scanf("%d",&sz[i]);
            for(int j=0;j<sz[i];j++){
                scanf("%lf%lf",&x,&y);
                a[i][j]=getp(x,y);
            }
        }
        scanf("%d",&m);
        db ans=0,s=0;P3 pre;
        bool f=0;
        for(int i=0;i<m;i++){
            scanf("%lf%lf",&x,&y);
            P3 ed = getp(x,y);
            if(i){
                ans+=Odist(pre,ed);
                q[0]=pre;int cnt=1;
                for(int i=0;i<c;i++)
                    for(int j=0;j<sz[i];j++)
                        if(checkSS(pre,ed,a[i][j],a[i][(j+1)%sz[i]],q[cnt]))cnt++;
                q[cnt++]=ed;
                sort(q,q+cnt,[&](const P3& a,const P3& b){return Odist(pre,a)<Odist(pre,b);});
                for(int i=1;i<cnt;i++){ //一开始的一段一定在陆地上的
                    if(f)s+=Odist(q[i],q[i-1]);
                    if(i<cnt-1)f=!f;
                }
            }
            pre=ed;
        }
        printf("%.11f %.11f
    ",ans*R,s*100/ans);
        return 0;
    }
    
  • 相关阅读:
    freemarker 遍历 hashmap 到select option
    三分钟跑起jsblocks
    hibernate_@GeneratedValue
    跑github上的Symfony项目遇到的问题2
    Activiti使用过程_1
    Symfony官方视频教程
    跑github上的Symfony项目遇到的问题
    剧本杀
    随遇而安
    开发者职场心得
  • 原文地址:https://www.cnblogs.com/MXang/p/11286253.html
Copyright © 2011-2022 走看看