Rendezvous on a Tetrahedron(四面体爬行)

原题: https://cn.vjudge.net/problem/UVALive-8372

题意:

有两只虫,延一个正四面体爬行(一只l1,角1,一只l2,角2),爬过边界时角度不变(保证不爬过),问最后是否停在一个面

解析:

爬行的路径全部拆开成到平面,就变成了这样
在这里插入图片描述
算出最终点的坐标后,发现往左移2单位或上下移 2 3 2\sqrt3 单位所在的块是一样的。最后拉到x:0~2 y: 2 3 2\sqrt3 的位置,用叉积判断点在哪个三角形里面。如果两个点在同一个三角形里面就YES

#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){}
    Point operator-(const Point &a)const{
        Point b(x-a.x,y-a.y);
        return b;
    }
};
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));
}
double cha(Point a,Point b){
    return a.x*b.y-a.y*b.x;
}

int ck(Point a,node b){
    if(dcmp(cha(a-b.p1 , a-b.p2))*dcmp(cha(b.p3-b.p1 , b.p3-b.p2))>0
       &&dcmp(cha(a-b.p3 , a-b.p2))*dcmp(cha(b.p1-b.p3 , b.p1-b.p2))>0
       &&dcmp(cha(a-b.p1 , a-b.p3))*dcmp(cha(b.p2-b.p1 , b.p2-b.p3))>0) return 1;
    return 0;

}
int judge(Point x){
    for(int i=0;i<ve.size();i++){
        if(ck(x,ve[i])) {
            //printf("(%.3f,%.3f) in (%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)\n",
            //       x.x,x.y, ve[i].p1.x,ve[i].p1.y, ve[i].p2.x,ve[i].p2.y, ve[i].p3.x,ve[i].p3.y);
            return ve[i].blo;
        }
        //else printf("(%.3f,%.3f) notin (%.3f,%.3f)(%.3f,%.3f)(%.3f,%.3f)\n",
        //           x.x,x.y, ve[i].p1.x,ve[i].p1.y, ve[i].p2.x,ve[i].p2.y, ve[i].p3.x,ve[i].p3.y);
    }
}


char x1[3],x2[3];
double d1,l1,d2,l2;
int main(){
    init();
    while(scanf("%s%lf%lf%s%lf%lf",x1,&d1,&l1,x2,&d2,&l2)!=EOF){
        double d;
        if(x1[0]=='B'&&x1[1]=='C')d=d1;
        else if(x1[0]=='C'&&x1[1]=='B')d=60.0-d1;
        else if(x1[0]=='D'&&x1[1]=='C')d=120.0-d1;
        else if(x1[0]=='C'&&x1[1]=='D')d=60.0+d1;
        else if(x1[0]=='B'&&x1[1]=='D')d=180.0-d1;
        else if(x1[0]=='D'&&x1[1]=='B')d=120.0+d1;
        d=d/180.0*acos(-1);
        double x=l1*cos(d),y=l1*sin(d);
        while(x<-eps)x+=2.0;
        while(x>2.0+eps)x-=2.0;
        double tt=2.0*sqrt(3.0);
        while(y<-eps)y+=tt;
        while(y>tt+eps)y-=tt;

        Point A(x,y);
        int block1=judge(A);

        //printf("A(%.3f,%.3f) : %d\n",x,y,block1);

        if(x2[0]=='B'&&x2[1]=='C')d=d2;
        else if(x2[0]=='C'&&x2[1]=='B')d=60.0-d2;
        else if(x2[0]=='D'&&x2[1]=='C')d=120.0-d2;
        else if(x2[0]=='C'&&x2[1]=='D')d=60.0+d2;
        else if(x2[0]=='B'&&x2[1]=='D')d=180.0-d2;
        else if(x2[0]=='D'&&x2[1]=='B')d=120.0+d2;
        d=d/180.0*acos(-1);
        x=l2*cos(d),y=l2*sin(d);
        while(x<-eps)x+=2.0;
        while(x>2.0+eps)x-=2.0;
        while(y<-eps)y+=tt;
        while(y>tt+eps)y-=tt;

        Point B(x,y);
        int block2=judge(B);

        //printf("B(%.3f,%.3f) : %d\n",x,y,block2);

        if(block1==block2)printf("YES\n");
        else printf("NO\n");
    }
}
//CD 30 1 DB 30 1 BC 1 1 DB 59 1 BC 29 20 BC 32 20

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/84202991