Created
August 22, 2017 09:13
-
-
Save Sd-Invol/1661078c7f19d5e5227f37d3af27f97a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
using namespace std; | |
const int N = 1005; | |
const double eps = 1e-7 , pi = acos(-1.0); | |
inline int dcmp(double x) { | |
return (x > eps) - (x < -eps); | |
} | |
struct Point { | |
double x , y; | |
Point (double x = 0 , double y = 0) : x(x) , y(y) {} | |
void input() { | |
scanf("%lf%lf",&x,&y); | |
} | |
bool operator < (const Point& R) const { | |
if (dcmp(x - R.x) == 0) | |
return dcmp(y - R.y) < 0; | |
return dcmp(x - R.x) < 0; | |
} | |
bool operator == (const Point& R) const { | |
return dcmp(x - R.x) == 0 && dcmp(y - R.y) == 0; | |
} | |
Point operator + (const Point& R) const { | |
return Point(x + R.x , y + R.y); | |
} | |
Point operator - (const Point& R) const { | |
return Point(x - R.x , y - R.y); | |
} | |
Point operator * (const double& R) const { | |
return Point(x * R , y * R); | |
} | |
Point operator / (const double& R) const { | |
return Point(x / R , y / R); | |
} | |
double operator ^ (const Point& R) const { | |
return x * R.y - y * R.x; | |
} | |
double operator % (const Point& R) const { | |
return x * R.x + y * R.y; | |
} | |
double len() { | |
return sqrt(*this % *this); | |
} | |
double angle() { | |
return atan2(y , x); | |
} | |
}; | |
bool OnRay(Point P , Point a1 , Point a2) { | |
double len = (P - a1).len(); | |
if (dcmp(len) == 0) return true; | |
a1 = P - a1 , a2 = P - a2; | |
return dcmp((a1 ^ a2) / len) == 0 && dcmp(a1 % (a2 - a1)) >= 0; | |
} | |
double GetLineIntersection(Point P , Point v , Point Q , Point w) { | |
Point u = P - Q; | |
return (w ^ u) / (v ^ w); | |
} | |
Point GetLineProjection(Point P , Point A , Point v) { | |
return A + v * (v % (P - A) / (v % v)); | |
} | |
int n; | |
Point p[N] , P , V; | |
double r[N]; | |
void work() { | |
for (int i = 0 ; i < n ; ++ i) { | |
scanf("%lf%lf%lf" , &p[i].x , &p[i].y , &r[i]); | |
r[i] = -log10(r[i]); | |
//cout << r[i] << endl; | |
} p[n] = p[0]; | |
P = Point(0 , 0); | |
scanf("%lf%lf" , &V.x, &V.y); | |
V = V / V.len(); | |
double I = 0; | |
int res = 0 , pre = -1; | |
while (I <= 4) { | |
++ res; | |
bool point = 0; | |
for (int i = 0 ; i < n ; ++ i) { | |
if (OnRay(p[i] , P , P + V)) { | |
point = 1; | |
break; | |
} | |
} | |
if (point) break; | |
for (int i = 0 ; i < n ; ++ i) { | |
if (i == pre) continue; | |
Point w = p[i + 1] - p[i]; | |
if (dcmp(w ^ V) == 0) continue; | |
double t0 = GetLineIntersection(P , V , p[i] , w); | |
//cout << t0 << endl; | |
if (dcmp(t0) <= 0) continue; | |
double t1 = GetLineIntersection(p[i] , w , P , V); | |
//cout << t1 << endl; | |
if (dcmp(t1) <= 0 || dcmp(t1 - 1) >= 0) continue; | |
//cout << "$$$" << endl; | |
Point nxt = P + V * t0; | |
I += r[i]; | |
Point O = GetLineProjection(P , nxt , Point(-w.y , w.x)); | |
V = O + O - P - nxt; | |
V = V / V.len(); | |
P = nxt; | |
//printf("%d : %f %f : %f %f | %f\n" , i , P.x , P.y , V.x , V.y , I); | |
pre = i; | |
break; | |
} | |
//break; | |
} | |
printf("%d\n" , res); | |
} | |
int main() { | |
while (~scanf("%d" , &n)) { | |
work(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment