G - Rendezvous on a Tetrahedron UVALive - 8372 计算几何 立体转平面

版权声明:本博客内容基本为原创,如有问题欢迎联系,转载请注明出处 https://blog.csdn.net/qq_41955236/article/details/84403834

题目链接:https://vj.e949.cn/f376bdaed6c2100cb7a5b94c3cb00e3d?v=1542418343

题意:

        给你一个单位长度的四面体,两只蜗牛同时从顶点A开始爬,告诉你它会向哪边爬以及与哪条边的夹角为多少,告诉你爬行的长度,问你最后这两只蜗牛是否再同一个平面上。

做法:

      和队友的讨论出真知啊!感慨一下。

      题目将立体问题转化为平面问题,因为往一个方向走之后,只要只要遇到哪条边那么下一个三角形也就能知道,所以其实可以直接将这些画成一个平面的图,以下是我心灵手巧的队长画的图。很容易发现,上下移动2根号3或者左右移动2之后得到的值是在同一个区域内的,即绕了一个圈,那么我们只要预处理出所有在横坐标0~2,纵坐标0~2根号3种的所有区域块,同时求得蜗牛最后平移后的落点,利用叉积进行运算即可。


#include<bits/stdc++.h>
using namespace std;

const double eps=1e-8;
struct Point{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
};
struct node{
    Point p1,p2,p3;
    int blo;
    node(Point p1,Point p2,Point p3,int blo):p1(p1),p2(p2),p3(p3),blo(blo){}
};
int dcmp(double a){
    if(fabs(a)<eps) return 0;
    if(a>0) return 1;
    return -1;
}
vector<node> ve;
void init(){
    double r=sqrt(3)/2;double r2=2.0*r,r3=3.0*r,r4=4.0*r;
        ve.push_back(node(Point(0,0),Point(1,0),Point(0.5,r),1));
        ve.push_back(node(Point(0,r2),Point(1,r2),Point(0.5,r),1));
        ve.push_back(node(Point(1,r2),Point(2,r2),Point(1.5,r3),1));
        ve.push_back(node(Point(1,r4),Point(2,r4),Point(1.5,r3),1));

        ve.push_back(node(Point(1,0),Point(2,0),Point(1.5,r),4));
        ve.push_back(node(Point(1,r2),Point(2,r2),Point(1.5,r),4));
        ve.push_back(node(Point(0,r2),Point(1,r2),Point(0.5,r3),4));
        ve.push_back(node(Point(0,r4),Point(1,r4),Point(0.5,r3),4));

        ve.push_back(node(Point(0,r2),Point(-0.5,r),Point(0.5,r),2));
        ve.push_back(node(Point(-0.5,r3),Point(0,r2),Point(0.5,r3),2));
        ve.push_back(node(Point(0.5,r),Point(1,0),Point(1.5,r),2));
        ve.push_back(node(Point(1.5,r),Point(2.5,r),Point(2,r2),2));
        ve.push_back(node(Point(1.5,r3),Point(2.5,r3),Point(2,r2),2));
        ve.push_back(node(Point(0.5,r3),Point(1.5,r3),Point(1,r4),2));

        ve.push_back(node(Point(0,0),Point(-0.5,r),Point(0.5,r),3));
        ve.push_back(node(Point(-0.5,r3),Point(0,r4),Point(0.5,r3),3));
        ve.push_back(node(Point(0.5,r),Point(1,r2),Point(1.5,r),3));
        ve.push_back(node(Point(1.5,r),Point(2.5,r),Point(2,0),3));
        ve.push_back(node(Point(1.5,r3),Point(2.5,r3),Point(2,r4),3));
        ve.push_back(node(Point(0.5,r3),Point(1.5,r3),Point(1,r2),3));
}
Point operator - (Point a, Point b){
    return Point(a.x - b.x, a.y - b.y);
}
double cha(Point a,Point b){
    /*cout<<a.x<<" "<<a.y<<endl;
    cout<<b.x<<" "<<b.y<<endl;
    cout<<a.x*b.y-a.y*b.x<<endl;*/
    return a.x*b.y-a.y*b.x;
}
int ck(Point a,node b){

    //cout<<cha(a-b.p1,a-b.p2)*cha(b.p3-b.p1,b.p3-b.p2)<<" "<<cha(a-b.p2,a-b.p3)*cha(b.p1-b.p2,b.p1-b.p3)<<" "<<cha(a-b.p3,a-b.p1)*cha(b.p2-b.p3,b.p2-b.p1)<<endl;
    if(dcmp(cha(a-b.p1,a-b.p2)*cha(b.p3-b.p1,b.p3-b.p2))>0&&dcmp(cha(a-b.p2,a-b.p3)*cha(b.p1-b.p2,b.p1-b.p3))>0&&dcmp(cha(a-b.p3,a-b.p1)*cha(b.p2-b.p3,b.p2-b.p1))>0) return 1;
    return 0;

}
int judge(Point x){
    for(int i=0;i<ve.size();i++){
        //cout<<i<<endl;
        if(ck(x,ve[i])) {

            return ve[i].blo;
        }
    }
}


char s1[5],s2[5];
double an1,len1,an2,len2;
int main(){
    init();
    while(~scanf("%s%lf%lf%s%lf%lf",s1,&an1,&len1,s2,&an2,&len2)){
        double ang;
        if(s1[0]=='B') ang=an1;
        else if(s1[0]=='C') ang=60.0+an1;
        else if(s1[0]=='D') ang=120.0+an1;

        ang=ang/180.0*acos(-1);
        double x,y,rr=2.0*sqrt(3);
        x=len1*cos(ang),y=len1*sin(ang);
        while(x<-eps) x+=2.0;
        while(x-2.0>eps) x-=2.0;
        while(y<-eps) y+=rr;
        while(y-rr>eps) y-=rr;

        Point fi(x,y);
        int blo1=judge(fi);

        if(s2[0]=='B') ang=an2;
        else if(s2[0]=='C') ang=60.0+an2;
        else if(s2[0]=='D') ang=120.0+an2;

        ang=ang/180.0*acos(-1);
        x=len2*cos(ang),y=len2*sin(ang);
        while(x<-eps) x+=2.0;
        while(x-2.0>eps) x-=2.0;
        while(y<-eps) y+=rr;
        while(y-rr>eps) y-=rr;

        Point se(x,y);
        int blo2=judge(se);
        //printf("blo1=%d  blo2=%d\n",blo1,blo2);
        if(blo1==blo2) printf("YES\n");
        else printf("NO\n");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41955236/article/details/84403834
今日推荐