Submission #638560
Source Code Expand
#include <bits/stdc++.h>//{{{
#define rep(i, n) for(int i = 0; i < (int)(n); ++i)
#define all(v) std::begin(v), std::end(v)
using namespace std;
template<class T>bool chmin(T&a,const T&b){if(a<=b)return false;a=b;return true;}
template<class T>bool chmax(T&a,const T&b){if(a>=b)return false;a=b;return true;}
//}}}
using Z = int;
using R = long double;
using P = complex<R>;
#define X real()
#define Y imag()
const R EPS = 1E-13;
const R PI = acos(R(-1));
int sgn(const R& r){ return (r > EPS) - (r < -EPS); }
int sgn(const R& a, const R &b){ return sgn(a - b); }
R dot(const P& a, const P& b){ return real(conj(a)*b); }
R det(const P& a, const P& b){ return imag(conj(a)*b); }
R angle(const P &p){ R theta = arg(p); return sgn(theta - PI) < 0 ? theta : -PI; }
R dPP(const P &a, const P &b){//{{{
return abs(a - b);
}//}}}
struct L{//{{{
P s, t;
L(){}
L(const P &s, const P &t) : s(s), t(t){}
};//}}}
struct C{//{{{
P o; R r;
C(){}
C(const P &o, const R &r) : o(o), r(r){}
};//}}}
istream &operator>>(istream &is, P &p){//{{{
R x, y; is >> x >> y;
p.real(x); p.imag(y);
return is;
}//}}}
namespace std{
bool operator < (const P& a, const P& b) {//{{{
return sgn(a.X, b.X) ? a.X < b.X : sgn(a.Y, b.Y) < 0;
}//}}}
}
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16, };
inline int ccw(const L& l, const P& p){//{{{
P b = p - l.s, c = l.t - l.s;
int scr = sgn(det(c, b));
if(scr) return scr < 0 ? RIGHT : LEFT;
if(sgn(dot(c, b)) < 0) return BACK;
if(sgn(norm(c) - norm(b)) < 0) return FRONT;
return ON;
}//}}}
struct Witch{//{{{
P o;
Z r, v;
Witch(){}
Witch(const P &o, const Z &r, const Z &v) : o(o), r(r), v(v){}
friend istream &operator>>(istream &is, Witch &w){
return is >> w.o >> w.r >> w.v;
}
};//}}}
R dLP(const L& l, const P& p){//{{{
return abs(det(l.t - l.s, p - l.s)) / abs(l.t - l.s);
}//}}}
// 二円の交点
vector<P> pS1S1(const C &a, const C &b){//{{{
R d = dPP(a.o, b.o);
R rc = (d * d + a.r * a.r - b.r * b.r) / (2 * d);
if(a.r * a.r - rc * rc < 0) return {};
R rs = sqrt(max(a.r * a.r - rc * rc, R(0)));
P dir = (b.o - a.o) / d;
return { a.o + dir * P(rc, rs), a.o + dir * P(rc, -rs) };
}//}}}
// 一点を通る, 円との接線
vector<P> tS1P(const C &c, const P &p){//{{{
R d = dPP(c.o, p);
if(d * d - c.r * c.r < 0) return {};
R r = sqrt(max(d * d - c.r * c.r, R(0)));
return pS1S1(c, C(p, r));
}//}}}
// 二円の共通接線の接点
vector<P> lS1S1(C a, C b){//{{{
vector<P> res;
if(a.r < b.r) swap(a, b);
R d = dPP(a.o, b.o);
P v = (b.o - a.o) / d;
int s = sgn(a.r - b.r - d);
if(s > 0) return res; // a が b を含む
if(s == 0){ // a の内側に b が接している
P t = a.o + a.r * v, u = t + v * P(0, 1);
res.emplace_back(t);
res.emplace_back(u);
return res;
}
// 外接線
if(sgn(a.r - b.r) == 0){
P t = a.o + v * P(0, 1) * a.r;
P u = a.o - v * P(0, 1) * a.r;
res.emplace_back(t);
res.emplace_back(t + b.o - a.o);
res.emplace_back(u);
res.emplace_back(u + b.o - a.o);
}else{
R theta = PI/2 - asin((a.r - b.r) / d);
P e = polar(R(1), theta);
res.emplace_back(a.o + v * a.r * e);
res.emplace_back(b.o + v * b.r * e);
res.emplace_back(a.o + v * a.r / e);
res.emplace_back(b.o + v * b.r / e);
}
// 内接線
s = sgn(d - a.r - b.r);
if(s == 0){
P t = a.o + a.r * v;
res.emplace_back(t);
res.emplace_back(t + v * P(0, 1));
}else if(s > 0){
R theta = PI/2 - asin((a.r + b.r) / d);
P e = polar(R(1), theta);
res.emplace_back(a.o + v * a.r * e);
res.emplace_back(b.o - v * b.r * e);
res.emplace_back(a.o + v * a.r / e);
res.emplace_back(b.o - v * b.r / e);
}
return res;
}//}}}
R solve_easy(const vector<C> &cs, const P start, const P goal){//{{{
auto is_valid_point = [&](const P &p){//{{{
for(auto &c : cs) if(sgn(dPP(c.o, p), c.r) < 0) return false;
return true;
};//}}}
auto is_valid_line = [&](const L &l){//{{{
for(auto &c : cs){
if(sgn(dLP(l, c.o), c.r) > 0) continue;
const L m(c.o, c.o + (l.t - l.s) * P(0, 1));
if(sgn(dPP(c.o, l.s), c.r) < 0) return false;
if(sgn(dPP(c.o, l.t), c.r) < 0) return false;
if((ccw(m, l.s) | ccw(m, l.t)) == (LEFT | RIGHT))
return false;
}
return true;
};//}}}
auto is_valid_arc = [&](const C &c, const R a, const R b){//{{{
P pa = c.o + polar(c.r, a), pb = c.o + polar(c.r, b);
if(!is_valid_point(pa) or !is_valid_point(pb)) return false;
P dir = (pa - c.o) + (pb - c.o);
dir /= abs(dir);
return is_valid_point(c.o + dir * c.r);
};//}}}
set<P> ps = {start, goal};
for(auto &c : cs) for(auto &p : tS1P(c, start))
ps.emplace(p);
for(auto &c : cs) for(auto &p : tS1P(c, goal))
ps.emplace(p);
for(auto &a : cs) rep(dir, 4)
ps.emplace(a.o + polar(a.r, PI / 2 * dir));
for(auto &a : cs) for(auto &b : cs) for(auto &p : pS1S1(a, b))
ps.emplace(p);
for(auto &a : cs) for(auto &b : cs) for(auto &p : lS1S1(a, b))
ps.emplace(p);
// make graph
map<P, map<P, R>> g;
for(auto &p : ps) for(auto &q : ps) if(is_valid_line(L(p, q))){
if(g[p].count(q)) chmin(g[p][q], dPP(p, q));
else g[p][q] = dPP(p, q);
}
for(auto &c : cs){//{{{
vector<pair<R, P>> as;
for(auto &p : ps) if(sgn(dPP(p, c.o), c.r) == 0)
as.emplace_back(angle(p - c.o), p);
sort(all(as));
rep(i, as.size()){
const int j = (i + 1) % as.size();
R ai = as[i].first, aj = as[j].first;
P pi = as[i].second, pj = as[j].second;
if(is_valid_arc(c, ai, aj)){
R a = aj - ai;
if(a < 0) a += 2 * PI;
if(g[pi].count(pj)) chmin(g[pi][pj], c.r * a);
else g[pi][pj] = c.r * a;
if(g[pj].count(pi)) chmin(g[pj][pi], c.r * a);
else g[pj][pi] = c.r * a;
}
}
}//}}}
const R inf = 1E100;
map<P, R> d;
for(auto &p : ps) d[p] = inf;
priority_queue<pair<R, P>, vector<pair<R, P>>, greater<pair<R, P>>> pq;
pq.emplace(d[start] = 0, start);
while(!pq.empty()){
R c; P p; tie(c, p) = pq.top(); pq.pop();
if(d[p] < c) continue;
for(auto &qc : g[p]){
P q; R cc; tie(q, cc) = qc;
if(chmin(d[q], c + cc)) pq.emplace(d[q], q);
}
}
return d[goal];
}//}}}
template<class R, class CMP = less<R>, class F>
R find_max(R l, R r, F f){//{{{
constexpr R EPS = 1E-11;
const R phi = R(2) / (3 + sqrt(R(5)));
R ml = l + phi * (r - l), mr = r - phi * (r - l);
R fml = f(ml), fmr = f(mr);
while(mr - ml > EPS){
if(fml < fmr){ // '<' : max, '>' : min
l = ml; ml = mr; mr = r - phi * (r - l);
fml = fmr; fmr = f(mr);
}else{
r = mr; mr = ml; ml = l + phi * (r - l);
fmr = fml; fml = f(ml);
}
}
return ml;
}//}}}
void solve_hard(Witch w, P start, P goal, R speed){//{{{
start -= w.o;
goal -= w.o;
w.o = P(0, 0);
auto rot = [&](P p){//{{{
p /= abs(p);
start /= p;
goal /= p;
};//}}}
rot(start);
if(sgn(goal.Y) < 0) goal = conj(goal);
// w.o は原点, start は実軸上, goal は上半平面.
{ // 直接行く//{{{
P dir = goal - start;
// goal が殺される goal に直接つく
if(sgn((abs(goal) - w.r) / w.v, abs(dir) / speed) <= 0){
cout << "Impossible" << endl;
return;
}
auto f = [&](const R x){
P p = x * start + (1-x) * goal;
R t = abs(start - p) / speed;
return (w.r + w.v * t) - abs(p);
};
if(sgn(f(find_max<R>(0, 1, f))) <= 0){
cout << abs(dir) / speed << endl;
return;
}
}//}}}
auto dbl = [](const R &x){ return x * x; };
const R t1 = sqrt((dbl(start.X) - dbl(w.r)) / (dbl(speed) - dbl(w.v)));
if(sgn(w.r + t1 * w.v, abs(goal)) >= 0){
cout << "Impossible" << endl;
return;
}
P angle;
{//{{{
R xvdx = w.r * w.v + sqrt((dbl(speed) - dbl(w.v)) * (dbl(start.X) - dbl(w.r)));
R xvdy = sqrt(dbl(start.X * speed) - xvdx);
auto ps = pS1S1(C(w.o, w.r + t1 * w.v), C(start, t1 * speed));
assert(!ps.empty());
P p = ps.front().Y < 0 ? ps.back() : ps.front();
// => p * amp ----> goal
rot(p);
p = P(abs(p), 0);
angle = p - start;
}//}}}
// alpha * beta^theta
const R alpha = w.r + t1 * w.v;
const R beta = exp(w.v / sqrt(dbl(speed) - dbl(w.v)));
auto f = [&](const R theta){//{{{
P p = polar(alpha * pow(beta, theta), theta);
P dir = p * angle;
if(sgn(det(goal - p, p)) > 0) return R(+1);
return det(goal - p, dir);
};//}}}
assert(f(0) < 0);
assert(f(PI) > 0);
R theta = [&]{//{{{
R l = 0, r = PI;
rep(_, 1000){
R m = (l + r) / 2;
(f(m) < 0 ? l : r) = m;
}
return l;
}();//}}}
const P p = polar(alpha * pow(beta, theta), theta);
const R t12 = (abs(p) - w.r) / w.v;
const R t3 = abs(p - goal) / speed;
cout << t12 + t3 << endl;
}//}}}
int main(){
cout << std::fixed << std::setprecision(10);
P start, goal;
R speed;
int n;
cin >> start >> goal >> speed >> n;
// static witch, dymamic witch
vector<C> witch_s;
vector<Witch> witch_d;
rep(_, n){
Witch w; cin >> w;
if(w.v == 0) witch_s.emplace_back(w.o, w.r);
else witch_d.emplace_back(w);
}
if(n == 1 and !witch_d.empty() and witch_d[0].v < speed){
// hard problem
solve_hard(witch_d.front(), start, goal, speed);
}else{
// easy problem
const R res = solve_easy(witch_s, start, goal) / speed;
if(res > 1E50){
cout << "Impossible" << endl;
return 0;
}
for(auto &w : witch_d) if(sgn((dPP(goal, w.o) - w.r) / w.v, res) < 0){
cout << "Impossible" << endl;
return 0;
}
cout << res << endl;
}
return 0;
}
// vim:set foldmethod=marker commentstring=//%s:
Submission Info
Submission Time |
|
Task |
D - 魔女 |
User |
MiSawa |
Language |
C++11 (GCC 4.8.1) |
Score |
400 |
Code Size |
10975 Byte |
Status |
AC |
Exec Time |
198 ms |
Memory |
2032 KB |
Judge Result
Set Name |
Subtask1 |
Subtask2 |
Subtask3 |
Subtask4 |
Score / Max Score |
50 / 50 |
100 / 100 |
100 / 100 |
150 / 150 |
Status |
|
|
|
|
Set Name |
Test Cases |
Subtask1 |
11_rand00.txt, 11_rand01.txt, 11_rand02.txt, 11_rand03.txt, 11_rand04.txt, 11_rand05.txt, 11_rand06.txt, 11_rand07.txt, 11_rand08.txt, 11_rand09.txt, 11_rand10.txt, 11_rand11.txt, 11_rand12.txt, 11_rand13.txt, 11_rand14.txt, 11_rand15.txt, 11_rand16.txt, 11_rand17.txt, 11_rand18.txt, 11_rand19.txt, 11_rand20.txt, 11_rand21.txt, 11_rand22.txt, 11_rand23.txt, 11_rand24.txt |
Subtask2 |
11_rand00.txt, 11_rand01.txt, 11_rand02.txt, 11_rand03.txt, 11_rand04.txt, 11_rand05.txt, 11_rand06.txt, 11_rand07.txt, 11_rand08.txt, 11_rand09.txt, 11_rand10.txt, 11_rand11.txt, 11_rand12.txt, 11_rand13.txt, 11_rand14.txt, 11_rand15.txt, 11_rand16.txt, 11_rand17.txt, 11_rand18.txt, 11_rand19.txt, 11_rand20.txt, 11_rand21.txt, 11_rand22.txt, 11_rand23.txt, 11_rand24.txt, 21_rand00.txt, 21_rand01.txt, 21_rand02.txt, 21_rand03.txt, 21_rand04.txt, 21_rand05.txt, 21_rand06.txt, 21_rand07.txt, 21_rand08.txt, 21_rand09.txt, 21_rand10.txt, 21_rand11.txt, 21_rand12.txt, 21_rand13.txt, 21_rand14.txt, 21_rand15.txt, 21_rand16.txt, 21_rand17.txt, 21_rand18.txt, 21_rand19.txt, 21_rand20.txt, 21_rand21.txt, 21_rand22.txt, 21_rand23.txt, 21_rand24.txt |
Subtask3 |
11_rand00.txt, 11_rand01.txt, 11_rand02.txt, 11_rand03.txt, 11_rand04.txt, 11_rand05.txt, 11_rand06.txt, 11_rand07.txt, 11_rand08.txt, 11_rand09.txt, 11_rand10.txt, 11_rand11.txt, 11_rand12.txt, 11_rand13.txt, 11_rand14.txt, 11_rand15.txt, 11_rand16.txt, 11_rand17.txt, 11_rand18.txt, 11_rand19.txt, 11_rand20.txt, 11_rand21.txt, 11_rand22.txt, 11_rand23.txt, 11_rand24.txt, 21_rand00.txt, 21_rand01.txt, 21_rand02.txt, 21_rand03.txt, 21_rand04.txt, 21_rand05.txt, 21_rand06.txt, 21_rand07.txt, 21_rand08.txt, 21_rand09.txt, 21_rand10.txt, 21_rand11.txt, 21_rand12.txt, 21_rand13.txt, 21_rand14.txt, 21_rand15.txt, 21_rand16.txt, 21_rand17.txt, 21_rand18.txt, 21_rand19.txt, 21_rand20.txt, 21_rand21.txt, 21_rand22.txt, 21_rand23.txt, 21_rand24.txt, 31_rand00.txt, 31_rand01.txt, 31_rand02.txt, 31_rand03.txt, 31_rand04.txt, 31_rand05.txt, 31_rand06.txt, 31_rand07.txt, 31_rand08.txt, 31_rand09.txt, 31_rand10.txt, 31_rand11.txt, 31_rand12.txt, 31_rand13.txt, 31_rand14.txt, 31_rand15.txt, 31_rand16.txt, 31_rand17.txt, 31_rand18.txt, 31_rand19.txt, 31_rand20.txt, 31_rand21.txt, 31_rand22.txt, 31_rand23.txt, 31_rand24.txt |
Subtask4 |
41_rand00.txt, 41_rand01.txt, 41_rand02.txt, 41_rand03.txt, 41_rand04.txt, 41_rand05.txt, 41_rand06.txt, 41_rand07.txt, 41_rand08.txt, 41_rand09.txt, 41_rand10.txt, 41_rand11.txt, 41_rand12.txt, 41_rand13.txt, 41_rand14.txt, 41_rand15.txt, 41_rand16.txt, 41_rand17.txt, 41_rand18.txt, 41_rand19.txt, 41_rand20.txt, 41_rand21.txt, 41_rand22.txt, 41_rand23.txt, 41_rand24.txt |
Case Name |
Status |
Exec Time |
Memory |
11_rand00.txt |
AC |
34 ms |
1128 KB |
11_rand01.txt |
AC |
30 ms |
1132 KB |
11_rand02.txt |
AC |
33 ms |
1092 KB |
11_rand03.txt |
AC |
28 ms |
1052 KB |
11_rand04.txt |
AC |
31 ms |
1000 KB |
11_rand05.txt |
AC |
33 ms |
1028 KB |
11_rand06.txt |
AC |
30 ms |
1132 KB |
11_rand07.txt |
AC |
30 ms |
1008 KB |
11_rand08.txt |
AC |
32 ms |
992 KB |
11_rand09.txt |
AC |
29 ms |
1000 KB |
11_rand10.txt |
AC |
31 ms |
1132 KB |
11_rand11.txt |
AC |
30 ms |
1120 KB |
11_rand12.txt |
AC |
28 ms |
1060 KB |
11_rand13.txt |
AC |
28 ms |
1056 KB |
11_rand14.txt |
AC |
30 ms |
1120 KB |
11_rand15.txt |
AC |
28 ms |
1056 KB |
11_rand16.txt |
AC |
30 ms |
1056 KB |
11_rand17.txt |
AC |
30 ms |
1132 KB |
11_rand18.txt |
AC |
30 ms |
1124 KB |
11_rand19.txt |
AC |
31 ms |
1052 KB |
11_rand20.txt |
AC |
29 ms |
1000 KB |
11_rand21.txt |
AC |
31 ms |
964 KB |
11_rand22.txt |
AC |
29 ms |
960 KB |
11_rand23.txt |
AC |
31 ms |
1128 KB |
11_rand24.txt |
AC |
28 ms |
1056 KB |
21_rand00.txt |
AC |
33 ms |
1088 KB |
21_rand01.txt |
AC |
31 ms |
1216 KB |
21_rand02.txt |
AC |
38 ms |
1216 KB |
21_rand03.txt |
AC |
184 ms |
2032 KB |
21_rand04.txt |
AC |
30 ms |
1096 KB |
21_rand05.txt |
AC |
69 ms |
1216 KB |
21_rand06.txt |
AC |
29 ms |
960 KB |
21_rand07.txt |
AC |
31 ms |
1252 KB |
21_rand08.txt |
AC |
51 ms |
1384 KB |
21_rand09.txt |
AC |
46 ms |
1208 KB |
21_rand10.txt |
AC |
30 ms |
1132 KB |
21_rand11.txt |
AC |
48 ms |
1256 KB |
21_rand12.txt |
AC |
189 ms |
1600 KB |
21_rand13.txt |
AC |
32 ms |
988 KB |
21_rand14.txt |
AC |
30 ms |
992 KB |
21_rand15.txt |
AC |
60 ms |
1452 KB |
21_rand16.txt |
AC |
36 ms |
1304 KB |
21_rand17.txt |
AC |
30 ms |
1124 KB |
21_rand18.txt |
AC |
31 ms |
1212 KB |
21_rand19.txt |
AC |
198 ms |
1508 KB |
21_rand20.txt |
AC |
32 ms |
1084 KB |
21_rand21.txt |
AC |
40 ms |
1200 KB |
21_rand22.txt |
AC |
44 ms |
1196 KB |
21_rand23.txt |
AC |
45 ms |
1228 KB |
21_rand24.txt |
AC |
30 ms |
1056 KB |
31_rand00.txt |
AC |
193 ms |
1764 KB |
31_rand01.txt |
AC |
114 ms |
1248 KB |
31_rand02.txt |
AC |
125 ms |
1644 KB |
31_rand03.txt |
AC |
155 ms |
1344 KB |
31_rand04.txt |
AC |
120 ms |
1480 KB |
31_rand05.txt |
AC |
97 ms |
1240 KB |
31_rand06.txt |
AC |
83 ms |
1160 KB |
31_rand07.txt |
AC |
107 ms |
1284 KB |
31_rand08.txt |
AC |
48 ms |
1352 KB |
31_rand09.txt |
AC |
132 ms |
1624 KB |
31_rand10.txt |
AC |
126 ms |
1740 KB |
31_rand11.txt |
AC |
119 ms |
1384 KB |
31_rand12.txt |
AC |
54 ms |
1348 KB |
31_rand13.txt |
AC |
134 ms |
1612 KB |
31_rand14.txt |
AC |
72 ms |
1368 KB |
31_rand15.txt |
AC |
85 ms |
1352 KB |
31_rand16.txt |
AC |
118 ms |
1384 KB |
31_rand17.txt |
AC |
42 ms |
1348 KB |
31_rand18.txt |
AC |
75 ms |
1260 KB |
31_rand19.txt |
AC |
140 ms |
1480 KB |
31_rand20.txt |
AC |
34 ms |
1164 KB |
31_rand21.txt |
AC |
41 ms |
1220 KB |
31_rand22.txt |
AC |
45 ms |
1216 KB |
31_rand23.txt |
AC |
45 ms |
1252 KB |
31_rand24.txt |
AC |
30 ms |
1096 KB |
41_rand00.txt |
AC |
29 ms |
1136 KB |
41_rand01.txt |
AC |
29 ms |
1068 KB |
41_rand02.txt |
AC |
30 ms |
1048 KB |
41_rand03.txt |
AC |
28 ms |
1092 KB |
41_rand04.txt |
AC |
28 ms |
1132 KB |
41_rand05.txt |
AC |
29 ms |
1056 KB |
41_rand06.txt |
AC |
31 ms |
1008 KB |
41_rand07.txt |
AC |
30 ms |
1048 KB |
41_rand08.txt |
AC |
29 ms |
1096 KB |
41_rand09.txt |
AC |
29 ms |
1048 KB |
41_rand10.txt |
AC |
31 ms |
1192 KB |
41_rand11.txt |
AC |
30 ms |
948 KB |
41_rand12.txt |
AC |
31 ms |
1048 KB |
41_rand13.txt |
AC |
31 ms |
1052 KB |
41_rand14.txt |
AC |
30 ms |
1100 KB |
41_rand15.txt |
AC |
32 ms |
1224 KB |
41_rand16.txt |
AC |
34 ms |
1136 KB |
41_rand17.txt |
AC |
31 ms |
1176 KB |
41_rand18.txt |
AC |
31 ms |
1260 KB |
41_rand19.txt |
AC |
30 ms |
1216 KB |
41_rand20.txt |
AC |
29 ms |
1132 KB |
41_rand21.txt |
AC |
31 ms |
956 KB |
41_rand22.txt |
AC |
29 ms |
1132 KB |
41_rand23.txt |
AC |
29 ms |
1064 KB |
41_rand24.txt |
AC |
30 ms |
1224 KB |