Задача
Привал.
Путник двигался [latex]t_{1}[/latex] часов со скоростью [latex]v_{1}[/latex] , затем [latex]t_{2}[/latex] часов — со скоростью [latex]v_{2}[/latex] и [latex]t_{3}[/latex] часов — со скоростью [latex]v_{3}[/latex] .
За какое время он одолел первую половину пути, после чего запланировал привал?
[latex]t_{1}[/latex] | [latex]t_{2}[/latex] | [latex]t_{3}[/latex] | [latex]v_{1}[/latex] | [latex]v_{2}[/latex] | [latex]v_{3}[/latex] | Результат | Комментарии |
2 | 3 | 4 | 90 | 80 | 30 | 3.125 | пройдено |
9 | 85 | 3 | 450 | 230 | 20 | 42.826 | пройдено |
4.5 | 75.9 | 3.124 | 100 | 0 | 0 | 2.25 | продено |
Код программы:
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 |
#include <iostream> using namespace std; struct path { double time; double velocity; double length; }; void calc_length (struct path *s1); double solve (double half_path, struct path s1, struct path s2, struct path s3); int main() { struct path s1, s2, s3 ; double half_path; cin >> s1.time >> s2.time >> s3.time; cin >> s1.velocity >> s2.velocity >> s3.velocity; calc_length(&s1); calc_length(&s2); calc_length(&s3); half_path = (s1.length + s2.length + s3.length)/2; cout << solve( half_path, s1, s2, s3) << endl; return 0; } void calc_length (struct path *s){ s->length = s->time*s->velocity; } double solve (double half_path, struct path s1, struct path s2, struct path s3){ if (half_path <= s1.length) { return half_path/s1.velocity ; } else if (half_path <= (s1.length + s2.length)) { return s1.time + (half_path - s1.length)/s2.velocity ; } else { return s1.time + s2.time + (half_path - s1.length - s2.length); } } |
В задаче нужно было найти за какое время путник преодолеет половину пути. Для удобства работы с данными была введена структура данных path, которая включает в себя — время и скорость на участке, а также длину участка.
Расстояние и время вычисляется по формулам:
[latex]s=t\cdot v[/latex][latex]t=\frac{s}{v}[/latex]
Так как значения времени и скорости не могут быть отрицательными, то дополнительно были проверены граничные условия для скорости и времени.
Ссылка на код здесь.
Второе решение:
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 |
#include <iostream> using namespace std; int main() { double t1, t2, t3, T, T2; double v1, v2, v3, S; double s1, s2, s3; cin >> t1 >> t2 >> t3; cin >> v1 >> v2 >> v3; s1 = v1*t1; s2 = v2*t2; s3 = v3*t3; S = (s1 + s2 + s3)/2; if ( (T = S/v1) <= t1) { cout << T << endl; return 0; } else { T = t1; } if ( (T2 = (S-s1)/v2) <= t2) { T+=T2; cout << T << endl; return 0; } else { T += t2; } T += ((S-s1-s2)/v3); cout << T <<endl; return 0; } |
ссылка на код
Решение на Java:
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 |
import java.util.*; import java.lang.*; import java.io.*; class Main { public static void main (String[] args) { Scanner in = new Scanner(System.in); double t1, t2, t3, T, T2; double v1, v2, v3, S; double s1, s2, s3; t1=in.nextDouble(); t2=in.nextDouble(); t3=in.nextDouble(); v1=in.nextDouble(); v2=in.nextDouble(); v3=in.nextDouble(); s1 = v1*t1; s2 = v2*t2; s3 = v3*t3; S = (s1 + s2 + s3)/2; if ( (T = S/v1) <= t1) { System.out.println(T); return ; } else { T = t1; } if ( (T2 = (S-s1)/v2) <= t2) { T+=T2; System.out.println(T); return ; } else { T += t2; } T += ((S-s1-s2)/v3); System.out.println(T); return ; } } |
1. Проверять корректность данных не нужно.
2. Если Вы уже сделали структуру, то почему работаете как с отдельными переменными? Например, передаете в функцию get_length отдельные поля и потом полю же и присваиваете. Нужно просто передать всю структуру и пусть внутри функции все вычисляет и присваивает.
3. Удивительно много кода вышло для такой задачи. как думаете, почему?
1. Функцию is_params_valid я убрала.
2. И модифицировала соответствующим образом процедуру ( calc_length ).
3. Задача расчета разбита на под-задачи, введены дополнительные структуры данных. Это требует больше кода. Но это упрощает чтение и внесение изменений в программу в дальнейшем.
Ольга, не обижайтесь, но я такое решение не приму.
Задача рассчитана на человека изучающего язык первую неделю. Решается она в несколько строчек. Даже если подробно расписывать, то:
1. Находим общий путь (3 умножения и 2 сложения). Делим пополам и запоминаем в переменной s.
2. Если (t = S / v1) <= t1, значит привал был на первом участке и ответ t. Иначе t = t1 и проверяем дальше. 3. Если (tmp = (S - S1) / v2) <= t2, значит привал был на втором участке и ответ t += tmp. Иначе t += t2 и проверяем дальше. 4. t += (S - S1 - S2) /v3 и это ответ. Так получится? Я ничего не напутал? Вы проделали большую и сложную работу. Потратьте, пожалуйста, ещё немного времени, чтобы написать новый вариант программы по той схеме, которую я Вам порекомендовал. Добавьте новый код к Вашему отчёту. Будут ли обе программы давать одинаковый ответ?
Получилось не так лаконично, как я рассчитывал, но получилось.
Конечно засчитываю, молодец.