Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Как понять логику решения следующей задачи (ещё и "для начинающих" называется)?

garrip91 Ученик (136), закрыт 1 год назад
Задача "Конец уроков" (Решение):

Условие:

В некоторой школе занятия начинаются в 9:00. Продолжительность урока — 45 минут, после 1-го, 3-го, 5-го и т. д. уроков перемена 5 минут, а после 2-го, 4-го, 6-го и т. д. — 15 минут.
|
Дан номер урока (число от 1 до 10). Определите, когда заканчивается указанный урок.
|
Выведите два целых числа: время окончания урока в часах и минутах.

Решение, найденное в Интернете:

1. a = int(input())
|
2. a = a*45 + (a//2)*5 + ((a+1)//2-1)*15
|
3. print(a//60 + 9, a%60)

Моё понимание данной задачи:

1. a * 45 - это суммарная продолжительность уроков с 1-го по введённый пользователем;
|
2.1. a // 2 - кол-во 5-иминутных перемен до заданного пользователем урока;
|
2.2. (a // 2) * 5 - это суммарная продолжительность 5-иминутных перемен до заданного пользователем урока;
|
3. ((a+1)//2-1)*15 - ?

ИЗ 3-ГО ПУНКТА "МОЕГО ПОНИМАНИЯ" МНЕ ПОНЯТНО ТОЛЬКО ЧИСЛО "15" (ЗДЕСЬ, ВИДИМО, РЕЧЬ ИДЁТ О СУММАРНОЙ ПРОДОЛЖИТЕЛЬНОСТИ 15-ИМИНУТНЫХ ПЕРЕМЕН...).

КАК ПОНЯТЬ ИМЕННО ВОТ ЭТО:
"((a+1)//2-1)"
???

Помогите мне, пожалуйста, разобраться в 3-м пункте, уважаемые посетители данного интернет-ресурса!!!
Лучший ответ
Андрей Высший разум (422110) 4 года назад
15-минутная перемена происходит ПЕРЕД 3-м, 5-м, 7-м и т. д. уроком. (a + 1) // 2 возвращает 1 для 1-го и 2-го урока, 2 - для 3-го и 4-го, 3 - для 5-го и 6-го и т. д. Таким образом, (a + 1) // 2 на 1 больше нужного кол-ва 15-минутных перемен.
garrip91Ученик (136) 4 года назад
А можно поподробнее объяснить? Я вообще не понял! :-(
garrip91Ученик (136) 4 года назад
....для начала: почему именно "(a + 1) // 2" ???Неужели нет какой-то более гуманной альтернативы?...
Андрей Высший разум (422110) Куда уж проще? Это же арифметика для младших классов школы. И если ты понимаешь a // 2, то что мешает понять (a + 1) // 2? Просто выпиши на листочке бумаги в столбик значения a (например, от 1 до 10 ) и (a + 1) // 2.
Остальные ответы
Александр Ларин Мастер (1438) 4 года назад
N = int(input())
time = [50, 60, 50, 60, 50, 60, 50, 50, 50, 50]
our_time = 0

for i in range(N):
__our_time += time[i]

time_h = our_time // 60
time_os = our_time - (time_h * 60)

if time_os == 0:
__time_os = "00"

print(str(9 + time_h) + ":" + str(time_os))
com uradmir@outlook. UrУченик (101) 5 месяцев назад
В задании указано что циклов не должно быть
Sun Sunshine Мастер (1895) 4 года назад
a = a*45 + ((a+1)//2)*5 + ((a)//2)*15
вроде, так в данном случае, раз определяется ПОСЛЕ заданного кол-ва уроков, а не ПОСЛЕ, как в вышеприведенном в вопросе решении.
first-programmer Знаток (350) 4 года назад
Вообще тут все просто, так как даны удобные числа для уроков. То есть после не четных классов всегда +5 минут, после четных +15. Поэтому нужно просто использовать деление по модулю и в зависимости от результата прибавлять нужное число. Время урока фиксированное. Если бы в задаче время перемены не было бы так равномерно привязано к четным и не четным урокам, то решение было бы не таким простым и изящным.

То есть у вас на входе допустим 3.

function getClassEndTime(int $numberClasses, DateTime $startTime, int $classDuration)
{
$classDuration *= $numberClasses;
$startTime->add(new DateInterval("PT" . $classDuration . "M"));

for($numberClasses; $numberClasses >= 1; $numberClasses--) {
if ($numberClasses % 2 == 0) {
$startTime->add(new DateInterval("PT15M"));
} else {
$startTime->add(new DateInterval("PT5M"));
}
}

return $startTime->format("H:i");
}

$dateTime = new DateTime("2019-11-24 09:00");
echo getClassEndTime(3, $dateTime, 45);
garrip91Ученик (136) 4 года назад
Мне вообще непонятен Ваш ответ! :-(
com uradmir@outlook. UrУченик (101) 5 месяцев назад
В задании указано что циклов не должно быть
Day Today Ученик (101) 4 года назад
Возможно поможет. Для Python.
amount_lesson = 4
current_lesson = 1
start = 540

while current_lesson <= amount_lesson:
----if current_lesson % 2 == 0:
---------start += 5
----elif current_lesson % 2 != 0:
---------start += 15
----start += 45
----current_lesson += 1

total_hour = start // 60 % 24
total_minute1 = start % 60 // 10
total_minute2 = start % 60 % 10

print(str(total_hour) + ':' + str(total_minute1) + str(total_minute2))

__________________output_____________________
12:40

Удачи!
Witch Профи (802) 2 года назад
Дмитрий Саперов

Многим, наверное, кажется непонятным решение разработчиков:
a = int(input())
a = a*45 + (a//2)*5 + ((a+1)//2-1)*15
print(a//60 + 9, a%60)

Попробую пояснить логику. Итак, возьмем для начала ситуацию с нечетным числом уроков, пусть их будет 5 (возьмем за a). Как подсчитать время на малые (пятиминутки) и большие (пятнадцатиминутки) перемены? Понятно, что перемену после последнего урока мы не считаем, т. е. всего перемен будет 4 (всего перемен a -1), из них будет равное количество пятиминуток и пятнадцатиминуток. Значит и на пятиминутки, и на пятнадцатиминутки уйдет времени по (a-1)/2 (по половине из всего количества учитываемых перемен). Следовательно для ситуации с нечетным числом уроков формула подсчета времени на перемены такая:
5*(a-1)/2 + 15*(a-1)/2

С четными будет так: если взять за пример 6 уроков, то пятиминутки будут после 1, 3 и 5 уроков, т. е. формула подсчета пятиминуток простая: a/2. А вот пятнадцатиминуток будет меньше на одну (после 2 и 4), т. к. после 6 урока учебный день завершается и перемену отсиживать не надо. Поэтому для пятнадцатиминуток формула (a/2)-1.Выходит, что если количество уроков четное, то формула времени на перемены будет:
5*(a/2) + 15*(a/2-1)

Получилось 2 формулы:
- для нечетного: 5*(a-1)/2 + 15*(a-1)/2
- для четного: 5*(a/2) + 15*(a/2-1)

Если присмотреться, то с подсчетом для нечетного числа уроков, а именно ее части "(a-1)/2" есть одна особенность. Если число нечетное (допустим, 5), то (5-1)/2 = 2. Но на самом деле здесь мы можем заменить формулу "(a-1)/2" на "a//2", ведь 5//2 тоже будет 2.Теперь формулы выглядят так:
- для нечетного: 5*(a//2) + 15*(a//2)
- для четного: 5*(a/2) + 15*(a/2-1)

Точно также в формуле для четных можно "a/2" (4/2 = 2) поменять на "a//2" (4//2 = 2). Получается:
- для нечетного: 5*(a//2) + 15*(a//2)
- для четного: 5*(a//2) + 15*(a/2-1)

Теперь нужно будет еще раз уделить внимание формуле для нечетного числа уроков "a//2". На самом деле ее можно заменить на (a+1)//2-1. Проверяем: 5//2 = 2. Как и (5+1)//2 - 1 = 2.
На эту же формулу ((a+1)//2-1) можно заменить и "a/2-1", использующуюся для четного числа уроков. Ведь 4/2 - 1 = 1, как и 4+1//2 - 1 = 1. В итоге у нас совпала формула для четного и нечетного числа уроков и выглядит она так:
5*(a//2) + 15*((a+1)//2-1)
Прибавляем время на сами уроки (a*45) и получаем решение разработчиков. Честно говоря, я планировал понятно объяснить, но похоже какая-то замудренная хрень вышла, но раз написал, то уж оставлю, вдруг поможет кому.
https://www.youtube.com/watch?v=1cg_9FBg4e8
Павел КалмаковУченик (245) 1 год назад
ОТ ДУШИ !!! Очень помог. ПРоф
Владислав Ковалев Ученик (105) 1 год назад
x = int(input())
h = 45*x
y1 = (x//2) * 20
y2 = (x//2) * 20 - 15
tim1 = (h + y1)//60 + ((h + y1)%60)/100
tim2 = (h + y2)//60 + ((h + y2)%60) / 100
if x%2>0:
print(9.00+tim1)
else:
print(9.00+tim2)
Проверил,реально работает. Новичок поэтому метод более колхозный.
Penix Знаток (250) 1 год назад
На "умных" сайтах по питону есть копипаста этого решения.
Но нигде нет комментариев (#) с объяснением и обратной связи.
Наводит на мысль, что скопировано с англоязычного ресурса и товарищи просто не знают логики решения и не могут закомментировать.

По поводу второй строки a = a*45 + (a//2)*5 + ((a+1)//2-1)*15 мои мысли таковы:
a*45 # подсчет сумы затраченного времени на уроки в минутах.
(a//2) # проверка на четность
(a//2)*5 # добавляем ко всем четным урокам 5 минут перемены
((a+1)//2-1) # проверка на четность. 1 и 2 урок должен давать 0 в этих скобках ибо 15 минут это перемена после четных уроков. Перед первым уроком и после последнего не должно быть перемен. по этому при добавлении времени перемены ко времени урока, перемена берется прошедшая. То есть ко второму уроку добавиться 5 минут а не 15. Так же к последнему уроку добавиться прошедшая перемена, что исключит подсчет следующей перемены, занятия закончились на последнем уроке и перемены не нужны. (-1) обнуляет добавление времени перемены к первому уроку, ибо перемены перед ним не было а формула добавляет ко времени урока перемену которая прошла, то есть ту которая была перед уроком. Так же (-1) смещает добавление 15 минутных перемен, что бы время перемен не добавилось лишний раз.
Если убрать (-1) то первый урок закончиться в 10:00 вместо 9:45, добавиться ненужная перемена 0 урока которого не было.
Второй урок закончиться в 10:50 вместо 10:35, не самые лишние 15 минут.
Третий урок закончится в 11:50 вместо 11:35
Четвертый в 12:40 вместо 12:25
Смещение на 15 минут убирает (-1)

((a+1)//2-1)*15 # добавляем 15 минут ко всем не четным урокам.

a = a*45 + (a//2)*5 + ((a+1)//2-1)*15
print(a//60 + 9, a%60) # a//60 + 9 Деление без остатка на минуты в часе дает количество часов и добавляется 9, время со старта уроков. Минуты определяются остатком a%60.
Похожие вопросы