#include #include #include #include #include #include #include #include #include #include using namespace std; typedef complex point; const double PI = atan(1.0) * 4; ifstream fin("getout.txt"); #define cin fin struct circle { point center; double r; double p; circle () {} circle (double x, double y, double r, double p) : center(x, y), r(r), p(p) {} }; #define EPSILON 1.0E-6 double calc_energy(const vector& circles, double rad) { double energy = 0.0; for (int j = 0; j < circles.size(); ++j) { circle circ = circles[j]; circ.center = circles[j].center * polar(1.0, rad); if (circ.center.real() > 0) { double dist = fabs(circ.center.imag()); if (dist < circ.r + EPSILON) { return 500000.0; } if (dist < 2 * circ.r + EPSILON) { double d = dist - circ.r; energy += circ.p * (circ.r - d) / circ.r; } } else { double dist = abs(circ.center); //double dist = fabs(circ.center.imag()); if (dist < circ.r + EPSILON) { return 500000.0; } if (dist < 2 * circ.r + EPSILON) { double d = dist - circ.r; energy += circ.p * (circ.r - d) / circ.r; } } } return energy; } int level = 0; double iter(const vector& circles, double left_rad, double mid_rad, double right_rad, double left_ene, double mid_ene, double right_ene) { if (mid_ene >= 500000) { return 500000; } //cout << "enter level " << ++level << ", mid_rad = " << mid_rad << endl; double lm_rad = (left_rad + mid_rad) / 2; double mr_rad = (mid_rad + right_rad) / 2; double lm_ene = calc_energy(circles, lm_rad); double mr_ene = calc_energy(circles, mr_rad); if( right_rad - left_rad <= 0.000001 ) { level--; return mid_ene; } if (left_ene > lm_ene && lm_ene < mid_ene) { double d = iter(circles, left_rad, lm_rad, mid_rad, left_ene, lm_ene, mid_ene); if (fabs(d - mid_ene) < 0.0001) { level--; return d; } } if (mid_ene > mr_ene && mr_ene < right_ene) { double d = iter(circles, mid_rad, mr_rad, right_rad, mid_ene, mr_ene, right_ene); if (fabs(d - mid_ene) < 0.0001) { level--; return d; } } if (lm_ene > mid_ene && mid_ene < mr_ene) { double d = iter(circles, lm_rad, mid_rad, mr_rad, lm_ene, mid_ene, mr_ene); if (fabs(d - mid_ene) < 0.0001) { level--; return d; } } level--; return mid_ene; } double solve(const vector& circles) { const int NUM = 10000; vector energy(NUM); for (int i = 0; i < NUM; ++i) { double rad = i * 2 * PI / NUM; energy[i] = calc_energy(circles, rad); } double min_val = *min_element(energy.begin(), energy.end()); for (int i = 0; i < NUM; ++i) { if (energy[i] > min_val * 1.2) { continue; } int left_idx = (i - 1 + NUM) % NUM; int mid_idx = i; int right_idx = (i + 1) % NUM; double left = energy[left_idx]; double mid = energy[mid_idx]; double right = energy[right_idx]; if (left > mid && mid < right) { double left_rad = left_idx * 2 * PI / NUM; double mid_rad = mid_idx * 2 * PI / NUM; double right_rad = right_idx * 2 * PI / NUM; double ene = iter(circles, left_rad, mid_rad, right_rad, left, mid, right); if (ene < min_val) { min_val = ene; } } } return min_val; } int main() { if(!fin) return -1; int n; cin >> n; vector circles(n); for (int i = 0; i < n; ++i) { double x, y, d, r; cin >> x >> y >> d >> r; circles[i] = circle(x, y, d, r); } double x, y, e; cin >> x >> y >> e; point r(x, y); for (int i = 0; i < n; ++i) { circles[i].center -= r; } double min_absorb = solve(circles); if (e - min_absorb < 0) { cout << "No way to escape" << endl; } else { char buf[32]; sprintf(buf, "%.3f", e - min_absorb); cout << buf << endl; } return 0; }