#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; } |
English