Problem:
Problem G
  Rendezvous on a Tetrahedron
One day, you found two worms $P$ and $Q$ crawling on the surface of a regular tetrahedron with four vertices $A$, $B$, $C$ and $D$. Both worms started from the vertex $A$, went straight ahead, and stopped crawling after a while.
When a worm reached one of the edges of the tetrahedron, it moved on to the adjacent face and kept going without changing the angle to the crossed edge (Figure G.1).
Write a program which tells whether or not $P$ and $Q$ were on the same face of the tetrahedron when they stopped crawling.
You may assume that each of the worms is a point without length, area, or volume.
Figure G.1. Crossing an edge
Incidentally, lengths of the two trails the worms left on the tetrahedron were exact integral multiples of the unit length. Here, the unit length is the edge length of the tetrahedron. Each trail is more than 0:001 unit distant from any vertices, except for its start point and its neighborhood.
  This means that worms have crossed at least one edge. Both worms stopped at positions more than 0:001 unit distant from any of the edges.
The initial crawling direction of a worm is specified by two items: the edge $XY$ which is the first edge the worm encountered after its start, and the angle $d$ between the edge $AX$ and the direction of the worm, in degrees.
Figure G.2. Trails of the worms corresponding to Sample Input 1
Figure G.2 shows the case of Sample Input 1. In this case, $P$ went over the edge $CD$ and stopped on the face opposite to the vertex $A$, while $Q$ went over the edge $DB$ and also stopped on the same face.
Input
The input consists of a single test case, formatted as follows.
$X_PY_P$ $d_P$ $l_P$
$X_QY_Q$ $d_Q$ $l_Q$
$X_WY_W$ ($W = P,Q$) is the first edge the worm $W$ crossed after its start. $X_WY_W$ is one of
BC
,
CD
or
DB
.
An integer $d_W$ ($1 \leq d_W \leq 59$) is the angle in degrees between edge $AX_W$ and the initial direction of the worm $W$ on the face $\triangle AX_WY_W$.
An integer $l_W$ ($1 \leq l_W \leq 20$) is the length of the trail of worm $W$ left on the surface, in unit lengths.
Output
Output
YES
when and only when the two worms stopped on the same face of the tetrahedron. Otherwise, output
NO
.
Sample Input 1
CD 30 1
DB 30 1
Sample Output 1
YES
Sample Input 2
BC 1 1
DB 59 1
Sample Output 2
YES
Sample Input 3
BC 29 20
BC 32 20
Sample Output 3
NO

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i = 0; i < n; i++)
#define ll long long
#define P pair<long double, long double>

long double S(P a, P b, P c) {
  long double x1 = b.first - a.first;
  long double x2 = c.first - a.first;
  long double y1 = b.second - a.second;
  long double y2 = c.second - a.second;
  long double S1 = abs(x1 * y2 - x2 * y1);
  return S1;
}

bool isin(P x, P a, P b, P c) {
  long double eps = 1e-10;
  return abs(S(a, b, c) - (S(a, b, x) + S(a, c, x) + S(b, c, x))) < eps;
}
int solve(long double x1, long double x2) {
  for (int i = -300; i < 300; i++) {
    for (int j = -300; j < 300; j++) {
      long double x = (long double)i * 1.0 + (long double)j * 0.50;
      long double y = (long double)j * sqrt(3) / 2.0;
      if (isin({x1, x2}, {x, y}, {x + 0.5, y + sqrt(3) / 2.0},
               {x - 0.5, y + sqrt(3) / 2.0}) or
          isin({x1, x2}, {x, y}, {x + 0.5, y - sqrt(3) / 2.0},
               {x - 0.5, y - sqrt(3) / 2.0})) {
        // cout << i << " " << j << endl;
        if (i % 2 == 0 and j % 2 == 0)
          return 0;
        else if (i % 2 == 0)
          return 1;
        else if (j % 2 == 0)
          return 2;
        else
          return 3;
      }
    }
  }
  return 0;
}
int main() {
  string s1, s2;
  long double d1, d2, l1, l2;
  long double x1, x2, y1, y2;
  long double pi = acos(-1.0);
  cin >> s1 >> d1 >> l1;
  cin >> s2 >> d2 >> l2;
  if (s1 == "CD") d1 += 60;
  if (s1 == "DB") d1 += 120;
  if (s2 == "CD") d2 += 60;
  if (s2 == "DB") d2 += 120;
  x1 = l1 * cos(d1 * pi / 180.0);
  y1 = l1 * sin(d1 * pi / 180.0);
  x2 = l2 * cos(d2 * pi / 180.0);
  y2 = l2 * sin(d2 * pi / 180.0);
  cout << (solve(x1, y1) == solve(x2, y2) ? "YES" : "NO") << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3868
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i = 0; i < n; i++)
#define ll long long
#define P pair<long double, long double>

long double S(P a, P b, P c) {
  long double x1 = b.first - a.first;
  long double x2 = c.first - a.first;
  long double y1 = b.second - a.second;
  long double y2 = c.second - a.second;
  long double S1 = abs(x1 * y2 - x2 * y1);
  return S1;
}

bool isin(P x, P a, P b, P c) {
  long double eps = 1e-10;
  return abs(S(a, b, c) - (S(a, b, x) + S(a, c, x) + S(b, c, x))) < eps;
}
int solve(long double x1, long double x2) {
  for (int i = -300; i < 300; i++) {
    for (int j = -300; j < 300; j++) {
      long double x = (long double)i * 1.0 + (long double)j * 0.50;
      long double y = (long double)j * sqrt(3) / 2.0;
      if (isin({x1, x2}, {x, y}, {x + 0.5, y + sqrt(3) / 2.0},
               {x - 0.5, y + sqrt(3) / 2.0}) or
          isin({x1, x2}, {x, y}, {x + 0.5, y - sqrt(3) / 2.0},
               {x - 0.5, y - sqrt(3) / 2.0})) {
        // cout << i << " " << j << endl;
        if (i % 2 == 0 and j % 2 == 0)
          return 0;
        else if (i % 2 == 0)
          return 1;
        else if (j % 2 == 0)
          return 2;
        else
          return 3;
      }
    }
  }
  return 0;
}
int main() {
  string s1, s2;
  long double d1, d2, l1, l2;
  long double x1, x2, y1, y2;
  long double pi = acos(-1.0);
  cin >> s1 >> d1 >> l1;
  cin >> s2 >> d2 >> l2;
  if (s1 == "CD") d1 += 60;
  if (s2 == "DB") d2 += 120;
  x1 = l1 * cos(d1 * pi / 180.0);
  y1 = l1 * sin(d1 * pi / 180.0);
  x2 = l2 * cos(d2 * pi / 180.0);
  y2 = l2 * sin(d2 * pi / 180.0);
  cout << (solve(x1, y1) == solve(x2, y2) ? "YES" : "NO") << endl;
}
accuracy: 0.08433734939759036
time_ms: 10
memory_kb: 3748
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <complex>
#include <cassert>
#define rep(i, n) for(i = 0; i < n; i++)
using namespace std;

typedef complex<double> P;

const double PI = 3.14159265358979;

char xp, yp; double dp, lp;
char xq, yq; double dq, lq;

double calcTheta(char a, char b, int d) {
	double angle;
	
	if (a == 'D' && b == 'B') {
		angle = 0 + d;
	}
	if (a == 'B' && b == 'C') {
		angle = 60 + d;
	}
	if (a == 'C' && b == 'D') {
		angle = 120 + d;
	}
	return angle * PI / 180.0;
}

double cross(P a, P b) {
	return a.real() * b.imag() - a.imag() * b.real();
}

bool isIn(P a, P b, P c, P p) {
	double p1 = cross(b - a, p - a);
	double p2 = cross(c - b, p - b);
	double p3 = cross(a - c, p - c);
	if (p1 * p2 < 0) return false;
	if (p2 * p3 < 0) return false;
	if (p3 * p1 < 0) return false;
	return true;
}

bool isContained(P p, int id) {
	P base[4];
	base[0] = P(0, 0);
	base[1] = P(1, 0) * exp(P(0, 1) * PI / 3.0);
	base[2] = P(1, 0) * exp(P(0, 1) * PI * 2.0 / 3.0);
	base[3] = P(1, 0) * exp(P(0, 1) * PI * 3.0 / 3.0);
	
	P vec1 = P(2, 0);
	P vec2 = vec1 * exp(P(0, 1) * PI / 3.0);
	
	int T = 50;
	for (int i = -T; i <= T; i++) {
		for (int j = -T; j <= T; j++) {
			P center = base[id] + vec1 * (double)i + vec2 * (double)j;
			
			P inner[6];
			P outer[6];
			int k;
			
			double sq3 = sqrt(3.0);
			rep(k, 6) inner[k] = center + P(1, 0) * exp(P(0, 1) * (double)k * PI / 3.0);
			rep(k, 6) outer[k] = center + P(sq3, 0) * exp(P(0, 1) * (double)(k * PI / 3.0 + PI / 6.0));
			
			rep(k, 6) {
				//inner[k], inner[k + 1], outer[k]からなる三角形に、pが含まれるか？
				if (isIn(inner[k], inner[(k + 1) % 6], outer[k], p)) {
					return true;
				}
			}
		}
	}
	return false;
}

int calcAreaId(P p) {
	for (int i = 0; i < 4; i++) {
		if (isContained(p, i)) {
			return i;
		}
	}
	return -1;
}

int main() {
	cin >> xp >> yp >> dp >> lp;
	cin >> xq >> yq >> dq >> lq;
	
	double theta1 = calcTheta(xp, yp, dp);
	double theta2 = calcTheta(xq, yq, dq);
	
	P p1 = lp * exp(P(0, 1) * theta1);
	P p2 = lq * exp(P(0, 1) * theta2);
	
	int id1 = calcAreaId(p1); assert(id1 >= 0);
	int id2 = calcAreaId(p2); assert(id2 >= 0);
	
	if (id1 == id2) { cout << "YES" << endl; }
	else { cout << "NO" << endl; }
	
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3628
final_rank: 2

code_snippet: #include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<vector>
#include<tuple>
#include<queue>
#include<functional>
#define llint long long int
#define lldo long double
#define fir first
#define sec second
#define pub push_back
#define mp make_pair
#define mt make_tuple
#define res resize
const llint big=5e15;
const lldo pai=3.141592653589793238462643383279502884197;
void maxeq(int &a,int b){if(a<b){a=b;}}
bool mineq(llint &a,llint b){if(a>b){a=b;return true;}return false;}
using namespace std;
int solve(void){
	string xy;int d,L;cin>>xy>>d>>L;
	L*=1e5;
	int men;//??¢
	if(xy=="BC"){men=3;}
	else if(xy=="CD"){men=1;}
	else{men=2;}
	lldo zx=0,zy=0;//??§?¨?
	lldo kak=pai*5.0/3- d*pai/180.0;
	const lldo rot=sqrt((lldo)3.0);
	while(L--){
		zx+=1e-5*cos(kak);
		zy+=1e-5*sin(kak);
		if(zy<-rot/2.0){//???
			if(men==0){men=1;zx=-zx;zy=-rot-zy;kak+=pai;}
			else if(men==1){men=0;zx=-zx;zy=-rot-zy;kak+=pai;}
			else if(men==2){
				men=0;zx=0.25+zx/2;zy=-zx*rot;
				kak-=pai/3;
			}
			else if(men==3){
				men=0;zx=-0.25+zx/2;zy=zx*rot;
				kak+=pai/3;
			}
		}
		else if(zx/-zy<-rot/3.0){//??????
			if(men==0){
				men=3;
				kak-=pai/3;
				zy=-rot/2;
				zx=zx*2+0.5;
			}else{
				if(men==3){men=1;}
				else{men++;}
				kak+=pai/3;
				zx=-zx;
			}
		}
		else if(zx/-zy>rot/3.0){
			if(men==0){
				men=2;
				kak+=pai/3;
				zy=-rot/2;
				zx=zx*2-0.5;
			}else{
				if(men==1){men=3;}
				else{men--;}
				kak-=pai/3;
				zx=-zx;
			}
		}
	}
	return men;
}
int main(void){
	if(solve()==solve()){cout<<"YES"<<endl;}
	else{cout<<"NO"<<endl;}
	return 0;
}
accuracy: 1
time_ms: 620
memory_kb: 3492
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#include <iomanip>
 
using namespace std;
 
typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<LD, LD> PLDLD;
typedef vector<int> VI;
typedef vector<char> VB;
 
#define FOR(i,a,b) for(int i=(a);i<(int)(b);++i)
#define REP(i,n)  FOR(i,0,n)
#define CLR(a) memset((a), 0 ,sizeof(a))
#define ALL(a) a.begin(),a.end()
 
const LD eps=1e-10;
const long long INFLL=(LL)(1e9)*(LL)(1e9);
const int INF=1e9;
 
template<class T>
void chmin(T& a, const T b)
{
	if(a>b)
		a=b;
}
template<class T>
void chmax(T& a, const T b)
{
	if(a<b)
		a=b;
}
 
const LL pow(const LL p, const LL q)
{
	LL t=1;
	for(int i=0;i<q;i++)
		t*=p;
	return t;
}

template <typename T>
struct has_iter
{
	private:
		template <typename U>
		static constexpr true_type check(typename U::iterator*);
		template <typename U>
		static constexpr false_type check(...);

	public:
		static constexpr bool value = decltype(check<T>(nullptr))::value;
};

template<typename T, typename U = typename T::iterator>
void print(const T& container)
{
		auto&& first=begin(container), last=end(container);
		auto&& back=prev(last);
		for(auto e=first; e!=last; e=next(e))
			cout<<*e<<" \n"[e==back];
}

extern void* enabler;
template<typename Head, typename enable_if<!has_iter<Head>::value>::type*& = enabler>
void print(const Head& head)
{
	cout<<head<<endl;
}

template<typename Head, typename... Tail>
void print(const Head& head, const Tail&... tail)
{
	cout<<head<<" ";
	print(tail...);
}

void io_speedup()
{
	cin.tie(0);
	ios::sync_with_stdio(false);
}

template<typename T>
istream& operator >> (istream& is, vector<T>& vec)
{
	for(T& x: vec) is >> x;
	return is;
}

template<typename T>
vector<T> read(int n)
{
	vector<T> t(n);
	cin>>t;
	return t;
}

template<typename T>
T read()
{
	T t;
	cin>>t;
	return t;
}

typedef LD ld;
const ld pi =acos(-1.0);
typedef complex<ld> Point;
struct Line
{
	Point a,b;
	Line(Point a_, Point b_):a(a_),b(b_)
	{}
	Line():a(Point(0,0)),b(Point(0,0))
	{}
};
ld dot(Point a, Point b)
{
	return real(conj(a) * b);
}
ld cross(Point a, Point b)
{
	return imag(conj(a) * b);
}
int ccw(Point a,Point b, Point c)
{
	b-=a;
	c-=a;
	if(cross(b,c)>eps) return 1;
	if(cross(b,c)<-eps) return -1;
	if(dot(b,c) < 0) return 2;
	if(norm(b)<norm(c)) return -2;
	return 0;
}
int main()
{
	string s1,s2;
	double d1,w1;
	double d2,w2;
	cin>>s1>>d1>>w1;
	cin>>s2>>d2>>w2;
	auto cs=[](string s)
	{
		if(s=="BC")
			return 0;
		else if(s=="CD")
			return 60;
		return 120;
	};
	d1+=cs(s1);
	d2+=cs(s2);
	Point p1(cos(d1*(pi/180))*w1, sin(d1*(pi/180))*w1);
	Point p2(cos(d2*(pi/180))*w2, sin(d2*(pi/180))*w2);
	auto f=[&](Point p)
	{
		double t=sqrt(3)/2;
		int ans1=-1;
		REP(j,100)
		{
			for(int i=-100;i<100;i++)
			{
				if((i+j)%2==0)
				{
					Point a(i/2.0, t*j);
					Point b((i+1)/2.0, t*(j+1));
					Point c((i-1)/2.0, t*(j+1));
					int f1=ccw(a, p, b);
					int f2=ccw(b, p, c);
					int f3=ccw(c, p, a);
					if(abs(f1+f2+f3)==3)
					{
						//print("yes",i,j);
						int r=0;
						if(j%4==0 || j%4==3) r=2;
						if(j%2==0)
							ans1=(r+200-i)%4;
						else
							ans1=(r+i+200)%4;
					}
				}
				else
				{
					Point a((i-1)/2.0, t*j);
					Point b((i+1)/2.0, t*(j));
					Point c((i)/2.0, t*(j+1));
					int f1=ccw(a, p, b);
					int f2=ccw(b, p, c);
					int f3=ccw(c, p, a);
					if(abs(f1+f2+f3)==3)
					{
						//print("yes",i,j);
						int r=0;
						if(j%4==0 || j%4==3) r=2;
						if(j%2==0)
							ans1=(r+200-i)%4;
						else
							ans1=(r+i+200)%4;
					}
				}
			}
		}
		return ans1;
	};
	//print(p1.real(), p1.imag(), p2.real(), p2.imag());
	//print(f(p1), f(p2));
	if(f(p1)==f(p2))
	print("YES");
	else
	print("NO");
}
accuracy: 1
time_ms: 10
memory_kb: 3556
final_rank: 1