#include <vector> #include <map> #include <algorithm> #include <cstdio> using namespace std; int v0, v1, v2, v3; map<int, int> left; // (first, last) vector<pair<int, int>> right; // (first, last) typedef long double T; T eps = 1e-12; T lpass(T t, int p, int q) { auto it = left.upper_bound(p - (v1 - v2) * t + eps); // next one that passes if (it != left.begin()) { --it; } return max( t + T(q - p) / (v0 - v2), // how fast getting there max(T(q - it->second) / (v1 - v2), T(0)) // when interval gets there ); } int main() { int l; scanf("%d %d %d %d %d", &l, &v0, &v1, &v2, &v3); vector<char> a(l+1, '.'), b(l+1, '.'), c(l+1, '.'); for (int i=0; i<l; ++i) scanf(" %c", &a[i]); for (int i=0; i<l; ++i) scanf(" %c", &b[i]); for (int i=0; i<l; ++i) scanf(" %c", &c[i]); c[0] = '.'; { int p, q = l; for (int i=l; i>=0; --i) { if (a[i] == '.') { left.insert({i, q}); } else { q = i-1; } } } { int q = l; for (int i=l; i>=0; --i) { if (c[i] == '.') { if (!right.empty() && right.back().second == q) right.pop_back(); right.push_back({i, q}); } else { q = i-1; } } } int s[3]; for (int i=l; i>=0; --i) { if (a[i] == '#') break; s[0] = i; } for (int i=l; i>=0; --i) { if (b[i] == '#') break; s[1] = i; } for (int i=l; i>=0; --i) { if (c[i] == '#') break; s[2] = i; } int p = 0; T t = 0; for (int q=1; q<=s[1]; ++q) { if (b[q] == '#') continue; //fprintf(stderr, "T at %d %d: %.3Lf\n", p, q, t); if (q - p == 1) { t += 1. / (v0 - v2); // just ride; p = q; continue; } T t2 = lpass(t, p, q); // consider passing on the left; //fprintf(stderr, "Could pass on the left to %.3Lf\n", t2); while (!right.empty()) { //fprintf(stderr, "Considering slot %d - %d\n", right.back().first, right.back().second); T enter = max(t, T(right.back().first - p) / (v2 - v3)); T limit = T(right.back().second - q) / (v2 - v3); T exit = enter + T(q - p) / (v0 - v2); //fprintf(stderr, "Could start on %.3Lf and pass on the left to %.3Lf but it shuts down at %.3Lf\n", enter, exit, limit); if (exit + eps < t2 && (right.size() == 1 || exit <= limit + eps)) { t = exit; break; } if (right.size() == 1 || t2 + eps < limit) { t = t2; break; } right.pop_back(); } p = q; } //fprintf(stderr, "%.5Lf\n", t); T td1 = max(T((s[0] - s[1]) + t * (v1 - v2)) / (v0 - v1), T(0)); T td2 = max(T((s[2] - s[1]) - t * (v2 - v3)) / (v0 - v3), T(0)); printf("%.15Lf\n", t + max(td1, td2)); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | #include <vector> #include <map> #include <algorithm> #include <cstdio> using namespace std; int v0, v1, v2, v3; map<int, int> left; // (first, last) vector<pair<int, int>> right; // (first, last) typedef long double T; T eps = 1e-12; T lpass(T t, int p, int q) { auto it = left.upper_bound(p - (v1 - v2) * t + eps); // next one that passes if (it != left.begin()) { --it; } return max( t + T(q - p) / (v0 - v2), // how fast getting there max(T(q - it->second) / (v1 - v2), T(0)) // when interval gets there ); } int main() { int l; scanf("%d %d %d %d %d", &l, &v0, &v1, &v2, &v3); vector<char> a(l+1, '.'), b(l+1, '.'), c(l+1, '.'); for (int i=0; i<l; ++i) scanf(" %c", &a[i]); for (int i=0; i<l; ++i) scanf(" %c", &b[i]); for (int i=0; i<l; ++i) scanf(" %c", &c[i]); c[0] = '.'; { int p, q = l; for (int i=l; i>=0; --i) { if (a[i] == '.') { left.insert({i, q}); } else { q = i-1; } } } { int q = l; for (int i=l; i>=0; --i) { if (c[i] == '.') { if (!right.empty() && right.back().second == q) right.pop_back(); right.push_back({i, q}); } else { q = i-1; } } } int s[3]; for (int i=l; i>=0; --i) { if (a[i] == '#') break; s[0] = i; } for (int i=l; i>=0; --i) { if (b[i] == '#') break; s[1] = i; } for (int i=l; i>=0; --i) { if (c[i] == '#') break; s[2] = i; } int p = 0; T t = 0; for (int q=1; q<=s[1]; ++q) { if (b[q] == '#') continue; //fprintf(stderr, "T at %d %d: %.3Lf\n", p, q, t); if (q - p == 1) { t += 1. / (v0 - v2); // just ride; p = q; continue; } T t2 = lpass(t, p, q); // consider passing on the left; //fprintf(stderr, "Could pass on the left to %.3Lf\n", t2); while (!right.empty()) { //fprintf(stderr, "Considering slot %d - %d\n", right.back().first, right.back().second); T enter = max(t, T(right.back().first - p) / (v2 - v3)); T limit = T(right.back().second - q) / (v2 - v3); T exit = enter + T(q - p) / (v0 - v2); //fprintf(stderr, "Could start on %.3Lf and pass on the left to %.3Lf but it shuts down at %.3Lf\n", enter, exit, limit); if (exit + eps < t2 && (right.size() == 1 || exit <= limit + eps)) { t = exit; break; } if (right.size() == 1 || t2 + eps < limit) { t = t2; break; } right.pop_back(); } p = q; } //fprintf(stderr, "%.5Lf\n", t); T td1 = max(T((s[0] - s[1]) + t * (v1 - v2)) / (v0 - v1), T(0)); T td2 = max(T((s[2] - s[1]) - t * (v2 - v3)) / (v0 - v3), T(0)); printf("%.15Lf\n", t + max(td1, td2)); return 0; } |