Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/64: Рейтинг темы: голосов - 64, средняя оценка - 4.89
2 / 2 / 0
Регистрация: 22.04.2018
Сообщений: 18
1

Задача "Часы с боем" , Python

22.04.2018, 22:15. Показов 12859. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте! Вчера на отборочном туре я неудачно пыталась решить задачу "Часы с боем". На её решение потратила очень много времени и не решила ни её, ни большинство других задач. И очень расстроилась.
Условие такое:
Старинные часы бьют каждые полчаса. Причем в начале каждого часа они бьют столько раз, сколько сейчас часов (по 1 разу – в час ночи и в час дня, по 2 раза – в два часа ночи в два часа дня и т.д., в полночь и в полдень они бьют, соответственно, по 12 раз). И еще 1 раз они бьют в середине каждого часа.
Дан промежуток времени. Известно, что прошло строго меньше 24 часов (но при этом могли начаться новые сутки). Напишите программу, определяющую, сколько ударов сделали часы за это время.
Формат ввода:
В первой строке вводится начальный момент времени, во второй строке — конечный. Моменты времени задаются двумя целыми числами, разделяющимися пробелом. Первое число задает часы (от 0 до 23), второе — минуты (от 1 до 59, при этом оно не равно 30).
Формат вывода:
Выведите одно число — сколько ударов сделали часы за этот отрезок времени.
Примечание:
Заметьте, что время в задаче задается в 24-часовой форме записи, в то время как часы показывают (и соответственно, бьют) в 12-часовом режиме (т.е., например, в 13 часов часы бьют 1 раз).
Ограничение по времени: 1 секунда.
Ограничение по памяти: 256 мегабайт.

Примеры:

Входные данныеОтвет
0 1 
5 51 21
10 22 
11 5 12
6 52 
23 46140
5 59 
7 40 15
5 20 
5 25 0
16 17 
3 19 85
20 5 
7 4 81
8 55 
7 46 171
20 42 
9 43 100
1 45 
1 11 179


Моё не полное решение:
Python
1
2
3
4
5
6
7
8
9
# неполное решение, не проходит 70% тестов
h, m = map(int, input().split()) # начальный момент времени.
h1, m1 = map(int, input().split()) # конечный момент времени.
H = [ i+1 for i in range(h, h1)] # список кол-ва ударов в каждый i-ый час.
if m < 30 and m1 > 30:
    M = (((h1*60+m1)-(h*60+m))//60) + 1 # кол-во ударов в середине каждого часа.
elif m > 30 or m1 < 30:
    M = ((h1*60+m1)-(h*60+m))//60 # кол-во ударов в середине каждого часа.
print(sum(H) + M) # сколько раз часы суммарно били за время h,m - h1,m1.
Я совсем недавно начала изучать Python. Прошу помощи в решении этой задачки
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.04.2018, 22:15
Ответы с готовыми решениями:

Задача с олимпиады: Часы с боем
Всем привет. Где-то год назад была олимпиада, на которой была такая...

Часы с боем(олимпиадная задача)
Старинные часы бьют каждые полчаса. Причем в начале каждого часа они бьют столько раз, сколько...

Задача "Часы с боем" для школьников)
Старинные часы бьют каждые полчаса. Причем в начале каждого часа они бьют столько раз, сколько...

Часы с боем
нужно срочно решить задачу по программированию. Старинные часы бьют каждые полчаса.Причем в начале...

16
37 / 36 / 16
Регистрация: 11.03.2018
Сообщений: 95
23.04.2018, 01:39 2
Лучшего не получилось придумать, вообще не люблю задачи с часами
Python
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
def solution(data):
    from datetime import time
 
    data = list(map(int, data))
 
    t1 = time(data[0], data[1])
    t2 = time(data[2], data[3])
 
    weights_of_hours = {i: i for i in range(1, 13)}
    weights_of_hours.update({i: i - 12 for i in range(13, 24)})
    weights_of_hours.update({0: 12})
    w = weights_of_hours
 
    count = 0
 
    if t1.minute < 30 and t2.minute < 30:
        count += t2.hour - t1.hour
    elif t1.minute < 30 and t2.minute > 30:
        count += t2.hour - t1.hour + 1
    elif t1.minute > 30 and t2.minute < 30:
        count += t2.hour - t1.hour
    elif t1.minute > 30 and t2.minute > 30:
        count += t2.hour - t1.hour
 
    if count < 0:
            count += 24
 
    if t1.hour == t2.hour and t1.minute > t2.minute:
        count = 2 * sum(range(1, 13))
        count += 23
    elif t2.hour < t1.hour:
        for i in range(t1.hour + 1, 24):
            count += w[i]
        for i in range(t2.hour + 1):
            count += w[i]
    else:
        for i in range(t1.hour + 1, t2.hour + 1):
            count += w[i]
 
    return count
 
 
raw_data = """
0 1
5 51    21
10 22
11 5    12
6 52
23 46   140
5 59
7 40    15
5 20
5 25    0
16 17
3 19    85
20 5
7 4 81
8 55
7 46    171
20 42
9 43    100
1 45
1 11    179
"""
 
data = [raw_data.split()[i:i + 5] for i in range(0, len(raw_data.split()), 5)]
 
for i in data:
    a = solution(i[:4])
    print(a, end='\n')
# 21
# 12
# 140
# 15
# 0
# 85
# 81
# 171
# 100
# 179
1
2 / 2 / 0
Регистрация: 22.04.2018
Сообщений: 18
23.04.2018, 15:05  [ТС] 3
FilArt97,
Вау!!! Спасибо огромное!!! Буду сегодня изучать ваше решение.
0
Автоматизируй это!
Эксперт Python
7107 / 4610 / 1215
Регистрация: 30.03.2015
Сообщений: 13,236
Записей в блоге: 29
23.04.2018, 18:24 4
Yntra, вот вариант с функциями, тесты все проходят
Python
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
# Все часы в сутках
a_l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
 
 
def count_hits(start_hour, start_min, end_hour, end_min):
    """ Подсчет ударов в периоде"""
    # Обработка ситуации, когда почти сутки прошли
    if start_hour == end_hour and start_min > end_min:
        result_list = a_l
    else:
        # Все остальные ситуации
        result_list = a_l[start_hour:end_hour] if start_hour <= end_hour else a_l[start_hour:] + a_l[:end_hour]
    result = 0
    for x in result_list:
        # Если час от 13 до 24 то вычитаем 12 для подсчета
        x = x - 12 if x > 12 else x
        result += x
    # len(result_list) - 1  - это подсчет ударов между часами (в 30 минут)
    return (result + len(result_list) - 1) + count_hits_by_minutes(start_min, end_min)
 
 
def count_hits_by_minutes(start, end):
    """ Подсчитываем удары между часами в зависимости от минут"""
    result = 0
    if start < 30:
        result += 1
    if end > 30:
        result += 1
    return result
 
 
def calculate(start_time, end_time):
    """ Собственно решение, парсим ввод, отправляем целые числа в метод подсчет"""
    start_hour, start_min = int(start_time.split()[0]), int(start_time.split()[1])
    end_hour, end_min = int(end_time.split()[0]), int(end_time.split()[1])
    return count_hits(start_hour, start_min, end_hour, end_min)
 
 
assert (calculate('0 1', '5 50') == 21)
assert (calculate('10 22', '11 5') == 12)
assert (calculate('6 52', '23 46') == 140)
assert (calculate('5 59', '7 40') == 15)
assert (calculate('5 20', '5 25') == 0)
assert (calculate('16 17', '3 19') == 85)
assert (calculate('20 5', '7 4') == 81)
assert (calculate('8 55', '7 46') == 171)
assert (calculate('20 42', '9 43') == 100)
assert (calculate('1 45', '1 11') == 179)
1
2 / 2 / 0
Регистрация: 22.04.2018
Сообщений: 18
23.04.2018, 19:44  [ТС] 5
Welemir1,
Спасибо!!!

Добавлено через 15 минут
Пыталась сегодня доработать свой вариант со списком. Но опять неудача .
Извиняюсь за обилие комментариев в программе, но они помогают мне не повторяться и не сбиваться.
Осмелюсь предположить, что вариант решения со списками возможно будет изящнее.

Python
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
# не полное решение, не проходит 50% тестов
 
h, m = map(int, input().split()) # начальный момент времени.
h1, m1 = map(int, input().split()) # конечный момент времени.
 
#  h < h1 подсчёт часов и ударов в каждый час в течении всего промежутка времени.
 
H = [ i+1 for i in range(h, h1)] # список кол-ва ударов в каждый i-ый час.
#print(H)
 
#  h < h1 подсчёт минут и ударов в середине каждого часа в течении всего промежутка времени.
 
if m < 30 and m1 > 30:
    M = (((h1*60+m1)-(h*60+m))//60) + 1 # кол-во ударов в середине каждого часа.
elif m > 30 or m1 < 30:
    M = ((h1*60+m1)-(h*60+m))//60 # кол-во ударов в середине каждого часа.
#print(M)
 
z = sum(H) # сумма чисел списка, кол-ва ударов в каждый i-ый час.
 
#  h > h1 подсчёт часов и ударов в каждый час в течении всего промежутка времени.
# неправильный промежуток времени - это промежуток между начальным и конечным моментами времени не включающий значения 12 или 00 часов,
# и в неправильном промежутке времени нет 12 часового периода.  
 
if h > h1:
    H = [i+1 for i in range(h1, h)] # замена местами h и h1.
    #print(H) замена местами h и h1 и подсчёт: разницы ударов каждый час за 12 часов и неправильного промежутка времени.  
    H1 = 78 - sum(H) # 78 -это количество ударов каждый час за 12 часов (только часы)
    #print(H1) # кол-ва ударов в каждый час без 12 часового цикла. 
    z = H1 + 90 # 90 -это сколько раз часы суммарно били за 12 часов (часы + полчаса).
    #print(z) # кол-ва ударов в каждый час в течении всего промежутка времени.
    
#  h > h1 подсчёт минут и ударов в середине каждого часа.
    
    if m < 30 and m1 > 30:
        M = (((h*60+m)-(h1*60+m1))//60) + 1 # замена местами h и h1, кол-во ударов в середине каждого часа.
    elif m > 30 or m1 < 30:
        M = ((h*60+m)-(h1*60+m1))//60 # замена местами h и h1, кол-во ударов в середине каждого часа.
        M = 12 - M # 12-это количество ударов каждыe полчаса за 12 часов.
        #print(M) замена местами h и h1 и подсчёт: разницы ударов каждыe полчаса за 12 часов и неправильного промежутка времени.    
        
print(z + M) # сколько раз часы суммарно били за время h,m - h1,m1.
Добавлено через 1 минуту
0
Автоматизируй это!
Эксперт Python
7107 / 4610 / 1215
Регистрация: 30.03.2015
Сообщений: 13,236
Записей в блоге: 29
24.04.2018, 08:06 6
Цитата Сообщение от Yntra Посмотреть сообщение
Осмелюсь предположить, что вариант решения со списками возможно будет изящнее.
вполне может быть, только сначала нужно рабочий вариант сделать, а потом добиться его изящества. А что за отборочный тур, где ты эту задачу нашла? на нее сколько то времени давалось?
0
2 / 2 / 0
Регистрация: 22.04.2018
Сообщений: 18
24.04.2018, 12:02  [ТС] 7
Welemir1,
Это был отборочный тур в образовательный центр "Сириус", программа "Информатика юниоры".
Всего было 8 задач, и эта задача "Старинные часы" - не самая сложная. 8 задач нужно было решить за 2ч. 30мин.
Я решила всего две задачки. Нерешенные хочу тоже решить. Так как у меня нет пока навыков, решение занимает ну ооочень много времени.
0
2 / 2 / 0
Регистрация: 22.04.2018
Сообщений: 18
02.05.2018, 17:33  [ТС] 8
Вот и я решила эту задачку с помощью списков . Проходит 100% тестов . Интуиция подсказывала что я на верном пути,
но сообразить сразу не смогла. На форуме я видела, что "знатоки" свои решения оформляют в одну или несколько строк.
Прошу вашей помощи: как записать мой код компактней?

Python
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
h, m = map(int, input().split()) # начальный момент времени.
h1, m1 = map(int, input().split()) # конечный момент времени.
""" Подсчитываем удары каждый час без минут"""
H12 = [ i+1 for i in range(0, 12)] # создадим список кол-ва ударов в каждый час за 12часов
H48 = H12 * 4 # создадим список кол-ва ударов в каждый час за 48часов
Hh = H48[h:] # список кол-ва ударов в каждый час за 48часов, без начального момента времени h 
if h1>h:
    hr = h1-h # разница часов при h1>h        
elif h1<h:
    hr = (h1+24)-h # разница часов при h1<h    
elif h1==h:
    if m1>m:
        hr = 0 # разница часов при h1=h и m1>m                
    elif m1<m:
        hr = (h1+24)-h # разница часов при h1=h и m1<m        
Hr = Hh[:hr] # список кол-ва ударов в каждый час
HR = sum(Hr) # сумма кол-ва ударов в каждый час
""" Подсчитываем удары каждые полчаса в зависимости от минут"""
if m < 30 and m1 > 30:
    M = len(Hr)+1 # кол-во ударов в середине каждого часа если m < 30 и m1 > 30
elif m < 30 and m1 < 30:
    M = len(Hr)   # кол-во ударов в середине каждого часа если m < 30 и m1 < 30 
elif m > 30 and m1 < 30:
    M = len(Hr)-1 # кол-во ударов в середине каждого часа если m > 30 и m1 < 30
elif m > 30 and m1 > 30:
    M = len(Hr)   # кол-во ударов в середине каждого часа если m > 30 и m1 > 30
""" Подсчитываем удары каждый час плюс каждые полчаса"""
print(HR+M) # кол-во ударов часов за время от h, m до h1, m1
0
672 / 475 / 215
Регистрация: 06.09.2013
Сообщений: 1,306
02.05.2018, 20:14 9
Yntra,
Python
1
2
3
4
5
6
7
8
9
10
11
h_start, m_start = map(int, input().split())
h_end, m_end = map(int, input().split())
if (h_end < h_start) or (h_end == h_start and m_end < m_start): 
    h_end += 24
result = 0
h = h_start + 1
while h <= h_end:    
    result += h % 12 if h != 12 and h != 24 else 12 
    h += 1
result += h_end - h_start - 1 + (m_start < 30) + (m_end > 30) 
print(result)
1
2 / 2 / 0
Регистрация: 22.04.2018
Сообщений: 18
02.05.2018, 20:38  [ТС] 10
woldemas,
Вау!!! Очень интересное решение!!!
0
672 / 475 / 215
Регистрация: 06.09.2013
Сообщений: 1,306
02.05.2018, 20:53 11
Yntra, цикл лучше убрать, чтобы по-питоновски было, тогда еще меньше строк
Python
1
2
3
4
5
6
h_start, m_start = map(int, input().split())
h_end, m_end = map(int, input().split())
if (h_end < h_start) or (h_end == h_start and m_end < m_start): h_end += 24
result = sum(map(lambda h : 12 if h in {12, 24} else h % 12, range(h_start + 1, h_end + 1)))
result += h_end - h_start - 1 + (m_start < 30) + (m_end > 30)
print(result)
1
2 / 2 / 0
Регистрация: 22.04.2018
Сообщений: 18
02.05.2018, 21:04  [ТС] 12
woldemas,
С ума сойти !!! Я тоже так хочу налету решать . Спасибочки, буду изучать
0
636 / 476 / 179
Регистрация: 28.05.2012
Сообщений: 1,414
03.05.2018, 05:02 13
Цитата Сообщение от Welemir1 Посмотреть сообщение
a_l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
ну не кошерно же так...
Python
1
a_l = list(range(1, 25))
0
Автоматизируй это!
Эксперт Python
7107 / 4610 / 1215
Регистрация: 30.03.2015
Сообщений: 13,236
Записей в блоге: 29
03.05.2018, 05:45 14
Vigi, каюсь((( писал на коленке, думая потом отрефакторить
0
2 / 2 / 0
Регистрация: 22.04.2018
Сообщений: 18
03.05.2018, 16:55  [ТС] 15
woldemas !!!
Как вы подсчитали "удары каждые полчаса" - просто чума с True False !!!
Цитата Сообщение от woldemas Посмотреть сообщение
= h_end - h_start - 1 + (m_start < 30) + (m_end > 30)
sum(map(lambda... - пока не поняла как работает
0
672 / 475 / 215
Регистрация: 06.09.2013
Сообщений: 1,306
03.05.2018, 17:19 16
Цитата Сообщение от Yntra Посмотреть сообщение
sum(map(lambda... - пока не поняла как работает
Это тоже самое, что выше я в цикле писал:
Python
1
2
3
4
5
6
7
#подсчет количества ударов "каждый час"
h = h_start + 1 #первый раз будет бить (если будет) в следующий после h_start час
while h <= h_end:    # укладывается ли этот час в наш промежуток
    # далее суммируется количество ударов, h % 12 - столько раз будет бить в h часов (остаток от деления на 12)
    # кроме случаев когда 12 и 24 часа, тогда будет бить 12 раз
    result += h % 12 if h != 12 and h != 24 else 12  
    h += 1 #переходим к следующему часу
Через sum просто более короткая запись всего этого цикла.
range(h_start + 1, h_end + 1) - диапазон часов, в которые будет бить
map(lambda h : 12 if h in {12, 24} else h % 12, range(h_start + 1, h_end + 1)) - просчитать для каждого часа из диапазона количество ударов и сформировать соответствующую последовательность
sum(map(...)) - найти суммарное количество ударов (сумма последовательности, сформированной на предыдщем этапе
1
2 / 2 / 0
Регистрация: 22.04.2018
Сообщений: 18
03.05.2018, 18:31  [ТС] 17
woldemas!
Спасибо за объяснение!
0
03.05.2018, 18:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.05.2018, 18:31
Помогаю со студенческими работами здесь

Часы с боем
Помогите пожалуйста, не могу сообразить как это все изложить и организовать... Еще эту задачу нужно...

Часы с боем пробивают каждый час такое количество ударов
Часы с боем пробивают каждый час такое количество ударов, сколько их есть на циферблате с цифрами...

Задача о 3 ферзях и 2 ладьях: найти такие позиции, чтобы все поля оказались под боем
нужно решить задачу по расстановке на шахматную доску 3 ферзя и 2 ладьи.найти такие позиции,чтобы...

Цифровые часы на python
Здравствуйте, необходимо реализовать цифровые часы как заставку для пк (т.е. что бы выводились к...

Задача 2. Старинные часы
Задача 2. Старинные часы. Старинные часы бьют каждые 15 минут. В начале каждого часа они бьют...

Задача про часы
Тут есть вот такая интересная задачка: Есть некое понятие времени, в котором в сутках N часов. И...

Задача 3. Красочные часы
Задача 3. Красочные часы Ограничение по времени: 1 секунда Ограничение по памяти: 256 MiB Вы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru