На форумі обговорюються лише питання, пов'язані з олімпіадою
Ви не зайшли.
Щоб не чекати пів року, пропоную ділитись розв'язками тут.
#include <iostream> #include <cmath> #include <iomanip> using namespace std; int main() { double L, a1, a2, v, t; cin >> L >> a1 >> a2 >> v >> t; double T, t1,t2,t3,tx,vx; tx = (L - v*v/2/a1 - v*t - v*v/2/a2) / v; if (tx < 0) { t3 = t; double a,b,c; a=a1/2*(1.0 + a1/a2); b=a1*t; c=-L; double x1,x2; x1=(-b+sqrt(pow(b,2.0)-4*a*c))/(2*a); x2=(-b-sqrt(pow(b,2.0)-4*a*c))/(2*a); if (x1<0) { t1 = x2; t2 = a1*x2/a2; } else if (x2<0) { t1 = x1; t2 = a1*x1/a2; } else { if (x1<x2) { t1 = x1; t2 = a1*x1/a2; } else { t1 = x2; t2 = a1*x2/a2; } } } else { t2 = t + tx; t1 = sqrt((L - v*(t2) - v*v/2/a2) * 2 / a1); t3 = sqrt((L - v*(t2) - v*v/2/a1) * 2 / a2); } T = t1 + t2 + t3; cout << fixed << setprecision(8) << T; return 0; }
Вибачте, що не використовував pow(v,2.0) У записі v*v менше букоффф
Алгоритм розв'язку у коментарях до програмного коду нижче:
#include <iostream> #include <cmath> #include <iomanip> using namespace std; int main() { double L, a1, a2, v, t; cin >> L >> a1 >> a2 >> v >> t; double T, t1,t2,t3,tx,vx; //T-загальний час //t1,t2,t3 - тривалість руху на трьох ділянках //tx-час розгону до максимально можливої швидкості за умовою //vx-до якої максимальної швидкості можна розігнатись реально //Щоб проїхати найшвидше потрібно розігнатись до максимальної швидкості v //s1 = a1*t1*t1/2 s1 = v*v/2/a1 //s2 = v*(t+tx) //s3 = a2*t3*t3/2 s3 = v*v/2/a2 //L= v*v/2/a1 + v*(t+tx) + v*v/2/a2 //L= v*v/2/a1 + v*t + v*tx + v*v/2/a2 //звідки: tx = (L - v*v/2/a1 - v*t - v*v/2/a2) / v; //cout << tx << endl; //Якщо не можна розігнатись до максимальної швидкості if (tx < 0) { //тоді час рівномірного руху t3 повинен бути мінімальним t3 = t; //s1= vx*vx/2/a1 = a1*t1*t1/2 //s2 = vx*t //s3 = vx*vx/2/a2 = a2*t3*t3/2 //vx = a1*t1 = a2*t3 => t3 = a1*t1/a2 //L = s1 + s2 + s3 //знаходимо t1 //L = a1*t1*t1/2 + a1*t1*t + a2*(a1*t1/a2)*(a1*t1/a2)/2 //L = (a1/2)*t1*t1 + a1*t*t1 + (a1*a1/a2/2)*t1*t1 //L = (a1/2)*t1*t1 + a1*t*t1 + (a1*a1/a2/2)*t1*t1 //a1/2(1 + a1/a2)*t1*t1 + a1*t*t1 - L = 0 double a,b,c; a=a1/2*(1.0 + a1/a2); b=a1*t; c=-L; //находим t1 double x1,x2; x1=(-b+sqrt(pow(b,2.0)-4*a*c))/(2*a); x2=(-b-sqrt(pow(b,2.0)-4*a*c))/(2*a); if (x1<0) { t1 = x2; //находим t2 t2 = a1*x2/a2; } else if (x2<0) { t1 = x1; //находим t2 t2 = a1*x1/a2; } else { if (x1<x2) { t1 = x1; //находим t2 t2 = a1*x1/a2; } else { t1 = x2; //находим t2 t2 = a1*x2/a2; } } } //Якщо можна розігнатись до максимальної швидкості else { //Знаходимо t2 t2 = t + tx; //s1 + s2 + s3 – L = 0 //знаходимо t1 //a1*t1*t1/2 + v*(t2) + v*v/2/a2 - L = 0 t1 = sqrt((L - v*(t2) - v*v/2/a2) * 2 / a1); //знаходимо t3 //v*v/2/a1+ v*(t2) + a2*t3*t3/2 - L = 0 t3 = sqrt((L - v*(t2) - v*v/2/a1) * 2 / a2); } //знаходимо загальний час: T = t1 + t2 + t3; cout << fixed << setprecision(8) << T; return 0; }
Відредаговано LVV (2020-11-08 12:45:16)
Поза форумом
#include <bits/stdc++.h> using namespace std; double L, a1, a2, v, t; //функция, определяющая, можем ли мы при такой скорости //отсановится ровно на финише или до него(главное - не перескочить). bool can(double speed){ return speed*speed/(2*a1) + speed*t + speed*speed/(2*a2)-0.000000001 < L; } int main() { cin >> L >> a1 >> a2 >> v >> t; double left=0, speed, right=v; //подбираем максимально возможную скорость //двоичный поиск по ответу //и да: мне жутко обидно, что я набрал только 8/20 по //этой задаче ТОЛЬКО из-за того, что написал маловато нулей //в точности (0.00001 вроде). Сейчас - АС. while(right-left>0.000000001){ speed=(left+right)/2; if( can(speed) )left=speed; else right=speed; } /* тут дальше плохо написано, но суть в том, что из двух вариантов скорости right и left отбираем тот, который подходит. */ if( !can(right) )swap(left, right); //будем выводить только right double sp=right;//результирующая скорость double time=sp/a1+sp/a2;//время разгона и торможения L-=sp*sp/(2*a1)+sp*sp/(2*a2);//оставим только то расстояние, которое проедем равномерно printf("%.10f", L/sp+time); return 0; }
Відредаговано GeniusDP (2020-11-08 17:31:32)
Поза форумом
#include <cstdio> #include <cmath> using std::scanf; using std::printf; int main() { long double L,a1,a2,v,t; scanf("%Lg%Lg%Lg%Lg%Lg",&L,&a1,&a2,&v,&t); long double Q=1.0L/a1+1.0L/a2; if(L/v-0.5L*v*Q<t) v=2.0L*L/(t+std::sqrt(t*t+2.0L*L*Q)); printf("%.21Lg\n",L/v+0.5L*v*Q); return 0; }
Используется https://en.wikipedia.org/wiki/Quadratic … r's_method , которая бывает полезна как численно, так и аналитически (свободной обработкой случая A->0). Впрочем, в коде LVV catastrophic cancellation, вроде бы, не приводит к потере точности.
LVV написав:
Вибачте, що не використовував pow(v,2.0)
А в чём вообще может быть преимущество?
Поза форумом
FordPerfect написав:
А в чём вообще может быть преимущество?
Ну на сколько я знаю pow просто приятней читать.
Відредаговано GeniusDP (2020-11-10 17:26:36)
Поза форумом
python 2.7
L, a1, a2, v, t = map(float, raw_input().split()) a_h = 1.0/(1/a1+1/a2) L_cr = v*t + v**2/(2*a_h) if L > L_cr: print L/v+v/2.0/a_h else: print (2*L/a_h+t**2)**0.5
Відредаговано andervish (2020-11-11 19:21:48)
Поза форумом