#include <iostream> #include <string> #include <deque> #include <iomanip> #include <limits> using namespace std; struct Gap { int s, e; [[nodiscard]] int len() const { return e == -1 ? numeric_limits<int>::max() : e - s; } }; int L, v0, v1, v2, v3; deque<Gap> g1, g2, g3; auto gaps(const string &line) { deque<Gap> gaps; int gs{}, ge; bool in_gap = false; for (int i = 0; i < size(line); ++i) { if (line[i] == '.' && !in_gap) { in_gap = true; gs = i; } if (line[i] == '#' && in_gap) { in_gap = false; ge = i; gaps.push_back({gs, ge}); } } gaps.push_back({in_gap ? gs : (int)size(line), -1}); return gaps; } double right_overtake_time(double pos, double time, double max_time, deque<Gap>::iterator &iter) { int final_pos = g2[1].s; double d_pos = time * v3; iter = g3.begin(); while (iter->e != -1) { if (iter->e + d_pos > pos + 1) break; g3.pop_front(); iter = g3.begin(); } double exp_gap_len = final_pos - pos + 1 - v3 * (final_pos - pos) / v0; while (true) { double gs = max(pos, iter->s + d_pos); double rem_len = iter->len() - (gs - iter->s - d_pos); double end_time = time - (gs - pos) / v3 + (final_pos - pos) / v0; if (end_time > max_time) { return -1; } else if (exp_gap_len <= rem_len) { return end_time; } else if (iter->e != -1) { g3.pop_front(); iter = g3.begin(); } else { return -1; } } } double left_overtake_time(double pos, double time) { int final_pos = g2[1].s; double d_pos = time * v1; auto iter = g1.begin(); while (iter->e != -1) { auto n = next(iter); if (n->s + d_pos > pos) break; iter = n; g1.pop_front(); } if (iter->e == -1) { return time + (final_pos - pos) / v0; } double dtv0 = (final_pos + 1 - (iter->e + d_pos)) / v1; double dtv1 = (final_pos - pos) / v0; return time + max(dtv0, dtv1); } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> L >> v0 >> v1 >> v2 >> v3; v0 -= v2; v1 -= v2; v3 -= v2; v2 = 0; string l1, l2, l3; cin >> l1 >> l2 >> l3; l3[0] = '.'; g1 = gaps(l1); g2 = gaps(l2); g3 = gaps(l3); double ct{}, pos{}; while (size(g2) > 1) { ct += (g2.front().len() - 1.) / v0; pos = g2.front().e - 1; double dtl = left_overtake_time(pos, ct); auto r_curr_gap = g3.begin(); double dtr = right_overtake_time(pos, ct,dtl, r_curr_gap); ct = dtr == -1 ? dtl : dtr; g2.pop_front(); pos = g2.front().s; } double l1_curr_pos = g1.back().s + ct * v1; if (l1_curr_pos > pos) { double dt = (l1_curr_pos - pos) / (v0 - v1); pos += dt * v0; ct += dt; } double l3_curr_pos = g3.back().s + ct * v3; if (l3_curr_pos > pos) { double dt = (l3_curr_pos - pos) / (v0 - v3); ct += dt; } cout << fixed << setprecision(15) << ct << '\n'; }
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 109 110 111 112 113 114 115 116 117 118 119 120 | #include <iostream> #include <string> #include <deque> #include <iomanip> #include <limits> using namespace std; struct Gap { int s, e; [[nodiscard]] int len() const { return e == -1 ? numeric_limits<int>::max() : e - s; } }; int L, v0, v1, v2, v3; deque<Gap> g1, g2, g3; auto gaps(const string &line) { deque<Gap> gaps; int gs{}, ge; bool in_gap = false; for (int i = 0; i < size(line); ++i) { if (line[i] == '.' && !in_gap) { in_gap = true; gs = i; } if (line[i] == '#' && in_gap) { in_gap = false; ge = i; gaps.push_back({gs, ge}); } } gaps.push_back({in_gap ? gs : (int)size(line), -1}); return gaps; } double right_overtake_time(double pos, double time, double max_time, deque<Gap>::iterator &iter) { int final_pos = g2[1].s; double d_pos = time * v3; iter = g3.begin(); while (iter->e != -1) { if (iter->e + d_pos > pos + 1) break; g3.pop_front(); iter = g3.begin(); } double exp_gap_len = final_pos - pos + 1 - v3 * (final_pos - pos) / v0; while (true) { double gs = max(pos, iter->s + d_pos); double rem_len = iter->len() - (gs - iter->s - d_pos); double end_time = time - (gs - pos) / v3 + (final_pos - pos) / v0; if (end_time > max_time) { return -1; } else if (exp_gap_len <= rem_len) { return end_time; } else if (iter->e != -1) { g3.pop_front(); iter = g3.begin(); } else { return -1; } } } double left_overtake_time(double pos, double time) { int final_pos = g2[1].s; double d_pos = time * v1; auto iter = g1.begin(); while (iter->e != -1) { auto n = next(iter); if (n->s + d_pos > pos) break; iter = n; g1.pop_front(); } if (iter->e == -1) { return time + (final_pos - pos) / v0; } double dtv0 = (final_pos + 1 - (iter->e + d_pos)) / v1; double dtv1 = (final_pos - pos) / v0; return time + max(dtv0, dtv1); } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> L >> v0 >> v1 >> v2 >> v3; v0 -= v2; v1 -= v2; v3 -= v2; v2 = 0; string l1, l2, l3; cin >> l1 >> l2 >> l3; l3[0] = '.'; g1 = gaps(l1); g2 = gaps(l2); g3 = gaps(l3); double ct{}, pos{}; while (size(g2) > 1) { ct += (g2.front().len() - 1.) / v0; pos = g2.front().e - 1; double dtl = left_overtake_time(pos, ct); auto r_curr_gap = g3.begin(); double dtr = right_overtake_time(pos, ct,dtl, r_curr_gap); ct = dtr == -1 ? dtl : dtr; g2.pop_front(); pos = g2.front().s; } double l1_curr_pos = g1.back().s + ct * v1; if (l1_curr_pos > pos) { double dt = (l1_curr_pos - pos) / (v0 - v1); pos += dt * v0; ct += dt; } double l3_curr_pos = g3.back().s + ct * v3; if (l3_curr_pos > pos) { double dt = (l3_curr_pos - pos) / (v0 - v3); ct += dt; } cout << fixed << setprecision(15) << ct << '\n'; } |