#include #include #include #include using namespace std; //#define VISUALIZE #ifdef VISUALIZE #include #include static const double DELTA = 0.1; #endif double X[100000 + 1]; double Y[100000 + 1]; static const double EPS = 1e-4; static const double G = 9.8; double f(double x0, double y0, double v0, double theta, double x) { return y0 + (x - x0) * tan(theta) - G * (x - x0) * (x - x0) / (2.0 * v0 * v0 * cos(theta) * cos(theta)); } int main() { int N; double V; while (cin >> N >> V && N){ assert(1 <= N && N <= 10000); assert(1 <= V && V <= 10000); for (int i = 0; i < N; ++i){ cin >> X[i] >> Y[i]; assert(0 <= X[i] && X[i] <= 10000); assert(0 <= Y[i] && Y[i] <= 10000); #ifdef VISUALIZE cout << X[i] << " " << Y[i] << endl; #endif } #ifdef VISUALIZE cout << endl << endl; vector > trajectory; #endif X[N] = X[N - 1] + 1e-5; Y[N] = Y[N - 1] + 1e-5; double answer = 0; bool flying = false; double x0 = X[0]; //飛び始めた場所 double y0 = Y[0]; double theta; for (int i = 0; i < N - 1; ++i){ if (flying){ //飛んでる const double x1 = X[i + 1]; const double y1 = Y[i + 1]; const double xr = x1; const double yr = f(x0, y0, V, theta, xr); if (yr > Y[i + 1]){ #ifdef VISUALIZE for (double x = X[i]; x < X[i + 1]; x += DELTA){ const double y = f(x0, y0, V, theta, x); trajectory.push_back(make_pair(x, y)); } #endif continue; } double l = X[i]; double r = X[i + 1]; const double a0 = (Y[i + 1] - Y[i]) / (X[i + 1] - X[i]); const double b0 = Y[i] - a0 * X[i]; for (int loop = 0; loop < 50; ++loop){ const double m = (l + r) * 0.5; const double y = f(x0, y0, V, theta, m); const double y2 = a0 * m + b0; if (y < y2){ r = m; } else { l = m; } } const double x2 = (l + r) * 0.5; const double y2 = a0 * x2 + b0; #ifdef VISUALIZE for (double x = X[i]; x < x2; x += DELTA){ const double y = f(x0, y0, V, theta, x); trajectory.push_back(make_pair(x, y)); } trajectory.push_back(make_pair(x2, f(x0, y0, V, theta, x2))); //trajectory.push_back(make_pair(X[i + 1], Y[i + 1])); #endif if (x0 + EPS < x2 && X[i + 1] < x2 && x2 < X[i + 1] + EPS){ fprintf(stderr, "#Warning! x0:%lf X[i]:%lf x:%lf y:%lf\n", x0, X[i], x2, y2); } if (X[i + 1] - EPS < x2 && x2 < X[i + 1]){ fprintf(stderr, "#Warning! X[i + 1]:%lf x:%lf y:%lf\n", X[i + 1], x2, y2); } answer += hypot(X[i + 1] - x2, Y[i + 1] - y2); } else { //飛んでない answer += hypot(X[i + 1] - X[i], Y[i + 1] - Y[i]); #ifdef VISUALIZE trajectory.push_back(make_pair(X[i], Y[i])); #endif } flying = (Y[i + 1] - Y[i]) / (X[i + 1] - X[i]) > (Y[i + 2] - Y[i + 1]) / (X[i + 2] - X[i + 1]); if (flying){ theta = atan2(Y[i + 1] - Y[i], X[i + 1] - X[i]); x0 = X[i + 1]; y0 = Y[i + 1]; } } #ifndef VISUALIZE printf("%.20lf\n", answer); #endif #ifdef VISUALIZE if (!flying){ trajectory.push_back(make_pair(X[N - 1], Y[N - 1])); } for (vector >::iterator it = trajectory.begin(); it != trajectory.end(); ++it){ cout << it->first << " " << it->second << endl; } if (!flying){ cout << X[N - 1] + 1 << " " << Y[N - 1] << endl; } #endif } }