1. 程式人生 > >Rendezvous on a Tetrahedron(四面體爬行)

Rendezvous on a Tetrahedron(四面體爬行)

題意:

有兩隻蟲,延一個正四面體爬行(一隻l1,角1,一隻l2,角2),爬過邊界時角度不變(保證不爬過),問最後是否停在一個面

解析:

爬行的路徑全部拆開成到平面,就變成了這樣
在這裡插入圖片描述
算出最終點的座標後,發現往左移2單位或上下移232\sqrt3單位所在的塊是一樣的。最後拉到x:0~2 y: 232\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