В этом листке вам нужно будет решать задачи, связанные с датами и временем, поэтому прежде всего нужно понять, как хранить даты и время в программе. Конечно, лучше всего для типа данных “Дата” создать класс.
class Date:
У объектов этого класса будет три поля:
day
, month
, year
.
Подумайте, какие операции можно выполнять с датами. Например, можно преобразовывать даты в строки для удобного вывода или, наоборот, преобразовывать строки в даты. К датам можно прибавлять (вычитать) целые числа (например, прибавить число 1 — это получить следующую дату). Наконец, можно брать разность двух дат (это количество дней между ними).
Для преобразования номера месяца в строку лучше всего использовать список строк-названий:
MonthNames = ('', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')Для вывода названия дней недели также лучше использовать список:
DayOfTheWeek = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')
Данные списки лучше всего сделать глобальными и объявить в самом начале программы.
А вот для преобразования строки-названия месяца в число лучше использовать словарь:
MonthNums = {'January': 1, 'February': 2, 'March': 3, ...}
Если имя поля начинается с двух символов подчеркивания, например, __day
,
__month
, __year
, то эти поля являются “скрытыми”,
то есть доступ к ним можно получить только из методов класса. Для работы с этими
полями нужно использовать методы класса: конструкторы, метод __str__
,
перегруженные операции и т.д. При необходимости явно получить или изменить
значение поля пишутся специальные методы типа get_day
или set_day
.
Если специальному атрибуту класса с именем __slots__
присвоить значение,
в виде списка из нескольких текстовых строк, то только перечисленные в данном списке имена
могут использоваться в качестве имен полей (атрибутов) классов. Например:
class Date: __slots__ = ['__day', '__month', '__year']
Это также приведет к уменьшению времени обращения к атрибутам класса за счет другого способа хранения атрибутов в экземпляре класса.
Для определения номера дня в году лучше всего использовать константный
массив количества дней в каждом месяце:
Months = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
Ввод | Вывод |
---|---|
1 |
January 1 |
365 |
December 31 |
Ввод | Вывод |
---|---|
January 1 |
1 |
December 31 |
365 |
Считывание и преобразование даты оформляйте в виде отдельных методов класса.
Ввод | Вывод |
---|---|
12.10.2008 |
October 12, 2008 |
01.01.0001 |
January 1, 1 |
Считывание и преобразование даты оформляйте в виде отдельных методов класса.
Ввод | Вывод |
---|---|
October 12, 2008 |
12.10.2008 |
January 1, 1 |
01.01.0001 |
Алгоритм решения задачи оформите в виде метода NextDate() класса
Ввод | Вывод |
---|---|
12.10.2008 |
13.10.2008 |
31.12.2008 |
01.01.2009 |
Ввод | Вывод |
---|---|
13.10.2008 |
12.10.2008 |
01.01.2009 |
31.12.2008 |
Две даты заданы в формате dd.mm.yyyy,
каждая дата - в новой строке. Определите количество дней между этими
датами. Вторая дата больше первой.
Алгоритм решения задачи оформите в виде метода __sub__
Ввод | Вывод |
---|---|
01.01.0001 |
1 |
29.02.2004 |
366 |
Ввод | Вывод |
---|---|
12.10.2008 |
Sunday |
13.10.2008 |
Monday |
Задан день и месяц рождения в формате dd.mm. Задана текущая дата в формате dd.mm.yyyy. Определите, сколько дней осталось до дня рождения. Если сегодня - день рождения, то необходимо вывести 0.
Ввод | Вывод |
---|---|
19.04 |
0 |
05.05 |
16 |
29.02 | 1096 |
Пронумеруем все даты подряд, считая, что 01.01.0001 имеет номер 1, 02.01.0001 - номер 2 и т.д. По заданной дате определите ее порядковый номер.
Программа получает на вход число дат \(N\le 200000\), затем заданы \(N\) дат. Для каждой из них выведите ее порядковый номер.
Данную функцию лучше всего оформить в виде метода __int__
,
вызываемым при преобразовании объекта к типу int
.
Ввод | Вывод |
---|---|
2 |
1 |
Решите обратную задачу: определите дату по номеру дня.
Данную функцию лучше всего оформить в форме конструктора,
принимающего один параметр типа int
.
Ввод | Вывод |
---|---|
2 |
01.01.0001 |
Научитесь быстро вычислять разницу между двумя датами.
Программа получает на вход число N, не превосходящее 105. Далее идет 2N дат, при этом не гарантируется, что первая дата меньше второй.
Выведите N чисел: для каждой пары дат входного файла выведите их разность (которая может быть как положительной, так и отрицательной).
Ввод | Вывод |
---|---|
2 |
1 |
Для хранения времени удобно создать класс Time
с полями
hours
, minutes
, seconds
.
Времена будут, как правило, задаваться в формате hh:mm:ss
, где hh
принимает значения от 00 до 23, mm
и ss
- значения от 00 до 59
или в формате hh:mm
.
Часы показывают время в формате hh:mm:ss.
Определите количество секунд, которое прошло с начала суток.
Программа не должна содержать циклов для решения этой задачи.
Ввод | Вывод |
---|---|
00:01:01 |
61 |
Ввод | Вывод |
---|---|
09:00:00 |
09:01:30 |
23:59:59 |
00:00:00 |
Ввод | Вывод |
---|---|
14:00:00 |
07:10:30 |
22:00:00 |
09:00:00 |
Будильник в сотовом телефоне можно настроить так, чтобы он звонил каждый день в одно и то же время, либо в указанное время в определенный день недели. Независимо можно настроить несколько будильников.
По информации о будильниках и текущему времени и дню недели определите, когда прозвонит очередной будильник.
В первой строке вводится текущий день недели (число от 1 до 7), затем через пробел,
текущее время в формате HH:MM
.
Во второй строке вводится одно натуральное число N, не превосходящее 100 – количество будильников.
В следующих N строках вводится описание N будильников в таком же формате. Значение дня недели, равное 0, означает, что будильник звонит каждый день.
Выведите номер дня недели и время, когда будильник зазвонит в следующий раз, в таком же формате.
Ввод | Вывод |
---|---|
2 10:20 |
3 10:10 |
7 01:01 |
7 01:01 |
Таймер - это часы, которые умеют подавать звуковой сигнал по прошествии некоторого периода времени. Напишите программу, которая определяет, когда должен быть подан звуковой сигнал.
Первая строка входных данных содержит текущее время в формате HH:MM:SS
(с ведущими нулями).
При этом оно удовлетворяет ограничениям: HH — от 00 до 23, MM и SS - от 00 до 59.
Вторая строка входных данных содержит интервал времени, который должен быть измерен.
Интервал записывается в формате H:M:S
(где H, M и S — от 0 до 109, без ведущих нулей).
При этом если H=0 (или H=0 и M=0), то они могут быть опущены.
Например, 100:60
может быть записано и как 101:0
,
1:41:0
, 0:100:60
, 0:101:0
и т.д.
Запись 42
— это то же самое, что 0:0:42
,
а 100:100:100
то же самое, что 101:41:40
.
Выведите в формате HH:MM:SS
время, во сколько прозвучит звуковой сигнал.
При этом если сигнал прозвучит не в текущие сутки, то дальше должна следовать запись
+<кол во> days
. Например, если сигнал прозвучит на следующий день – то +1 days
.
Ввод | Вывод |
---|---|
01:01:01 |
01:01:01+2 days |
01:01:01 |
02:01:00 |
23:59:59 |
00:00:00+1 days |
На одном из московских вокзалов билеты продают N касс. Каждая касса работает без перерыва определенный промежуток времени по фиксированному расписанию (одному и тому же каждый день). Требуется определить, на протяжении какого времени в течение суток работают все кассы одновременно.
Программа получает на вход целое число N (0<N≤1000).
В каждой из следующих N строк записано время начало
и время окончания работы кассы в формате HH:MM
через пробел.
Время открытия означает, что в соответствующую ему минуту касса уже работает, а время закрытия что в соответствующую минуту касса уже не работает. Например, касса, открытая с 10:30 18:30 ежесуточно работает 480 минут.
Если время открытия совпадает с временем закрытия, то касса работает круглосуточно. Если первое время больше второго, то касса начинает работу до полуночи, а заканчивает на следующий день.
Требуется вывести одно число суммарное время за сутки (в минутах), на протяжении которого работают все N касс.
Ввод | Вывод |
---|---|
3 |
120 |
2 |
0 |
2 |
1 |
Имеется список людей с указанием их фамилии, имени и даты рождения. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять самого старшего человека из этого списка и выводить его фамилию, имя и дату рождения, а если имеется несколько самых старших людей с одинаковой датой рождения, то определять их количество.
На вход программе в первой строке подается количество людей в списке N. В каждой из последующих N строк находится информация в следующем формате:
<Фамилия> <Имя> <Дата рождения>
где <Фамилия>
– строка, состоящая не более, чем из 20 символов без пробелов,
<Имя>
– строка, состоящая не более, чем из 20 символов без пробелов,
<Дата рождения>
– строка, имеющая вид DD.MM.YYYY
.
Программа должна вывести дату рождения самого старшего человека в списке, затем через пробел его фамилию и имя. Если таких людей, несколько, то вместо фамилии и имени выводится их количество.
Ввод | Вывод |
---|---|
3 |
29.04.1995 Petr Sergeev |
3 |
01.05.1995 2 |
Имеется список сотрудников организации с указанием их фамилии, имени и даты рождения. Администрация ежедневно поздравляет всех сотрудников, родившихся в этот день. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять, в какой из дней года родилось больше всего сотрудников и выводить этот день (или несколько дней).
Формат входных данных аналогичен предыдущей задаче.
Программа должна вывести список дат, в которые наибольшее число сотрудников отмечает дни рождения
в формате DD.MM
по возрастанию дат, каждая дата в отдельной строке.
Ввод | Вывод |
---|---|
5 |
01.01 |
Имеется список сотрудников организации с указанием их фамилии, имени и даты рождения. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять фамилию и имя самого молодого сотрудника, празднующего свой день рождения в течение ближайших семи дней от текущей даты (включая текущую дату).
На вход программе в первой сроке подается текущая дата,
заданная в формате DD.MM.YYYY
.
Во второй строке подается количество людей в списке N. В каждой из последующих N строк находится информация о каждом сотруднике, как в задаче T.
Известно, что у всех сотрудников даты рождения различаются. Программа должна вывести фамилию
и имя самого молодого сотрудника, празднующего день рождения в ближайшие 7 дней
или сообщение No birthdays in next week
, если никто из сотрудников не празднует
день рождения в ближайшие 7 дней.
Ввод | Вывод |
---|---|
25.11.2010 |
Ivan Petrov |
25.11.2010 |
No birthdays in next week |
0.142857 |
Решите задачу про кассы в следующих ограничениях: число касс до 10000, время задано с точностью
до секунд в формате HH:MM:SS
.
Требуется определить, на протяжении какого времени (в секундах) в течение суток работают все кассы одновременно.
Ввод | Вывод |
---|---|
3 |
7200 |
2 |
0 |
2 |
1 |
Играет два человека. Задается какая-то дата високосного года. Каждый игрок на своем ходу называет более позднюю дату, увеличивая на 1 или на 2 либо день в месяце, либо месяц, но не то и другое сразу. При этом результат должен оставаться корректной датой. Игрок, назвавший 31 декабря, проигрывает. Кто выигрывает при правильной игре: первый или второй.
Программа получает на вход дату в формате DD.MM
и должна вывести
одно число: номер выигрывающего игрока.
Ввод | Вывод |
---|---|
30.12 |
2 |
29.12 |
1 |
29.11 |
2 |
Для каждого данного года посчитайте количество выходных дней в этом году (то есть количество суббот и воскресений).
Программа получает на вход число \(N\) (\(1\le N\le 10^6\)). В каждой из следующих \(N\) строк записано по одному числу от 2000 до \(10^9\) — номера годов.
Для каждого номера года выведите количество выходных дней в соответствующем годе.
Для ускорения ввода-вывода используйте для чтения объект sys.stdin, результат выводите в sys.stdout.
Ввод | Вывод |
---|---|
2 |
104 |
Напишите программу, которая выводит на экран календарь на год примерно в таком виде,
как это делает программа cal
.
Календарь состоит из блоков, каждый из которых соответствует одному месяцу. Блоки расположены в виде таблицы из k столбцов и 12/k строк (k выбирается делителем числа 12). Месяцы выводятся в следующем порядке: первая строка содержит блоки, соответствующие месяцам с первого по k-ый, следующая – с (k + 1)-го по 2k-ый, и т. д.
Ширина всех блоков в столбце должна быть одинакова, высота всех блоков равна семи (числу дней в неделе). Между блоками различных строк таблицы выводится пустая строка, в каждой строке между соседними блоками из разных столбцов выводится три пробела.
Блок, соответствующий месяцу, устроен следующим образом. Каждой (в том числе неполной) неделе данного месяца в блоке соответствует столбец, имеющий ширину, равную двум. Между двумя соседними столбцами в каждой строке выводится один пробел. Если несколько блоков располагаются в одном столбце календаря, то для выравнивания ширины в те блоки, которые содержат меньше недель, в конец добавляется необходимое число пустых столбцов-недель. При этом разные столбцы календаря могут иметь разную ширину.
Все числа месяца заносятся в блок, соответствующий этому месяцу. Число заносится в строку блока, соответствующую дню недели, на который приходится число в этом месяце. Число заносится в столбец блока, соответствующий неделе, к которой относится данное число. Однозначные числа дополняются слева одним пробелом. Таким образом, числа в столбце оказываются выравнены по правому краю.
![]() |
![]() |
Программа получает на вход описание года, календарь для которого следует вывести. Оно содержит три числа: \(d\) – день недели, на который приходится первое января (\(1\le d \le 7\)), \(l\); – является ли год високосным (\(l=1\) означает, что год является високосными, \(l=0\) – что не является) и \(k\) – количество столбцов в календаре (\(k\) – одно из чисел 1, 2, 3, 4, 6, 12).
Выведите календарь, отформатированный в соответствии с условием задачи. Проверяющая программа в этой задаче игнорирует пробелы в конце строк. В остальном календарь должен быть отформатирован в точности так, как описано в условии.
Ввод | Вывод |
---|---|
4 1 4 |
5 12 19 26 2 9 16 23 1 8 15 22 29 5 12 19 26 6 13 20 27 3 10 17 24 2 9 16 23 30 6 13 20 27 7 14 21 28 4 11 18 25 3 10 17 24 31 7 14 21 28 1 8 15 22 29 5 12 19 26 4 11 18 25 1 8 15 22 29 2 9 16 23 30 6 13 20 27 5 12 19 26 2 9 16 23 30 3 10 17 24 31 7 14 21 28 6 13 20 27 3 10 17 24 4 11 18 25 1 8 15 22 29 7 14 21 28 4 11 18 25 3 10 17 24 31 7 14 21 28 5 12 19 26 2 9 16 23 30 4 11 18 25 1 8 15 22 29 6 13 20 27 3 10 17 24 31 5 12 19 26 2 9 16 23 30 7 14 21 28 4 11 18 25 6 13 20 27 3 10 17 24 1 8 15 22 29 5 12 19 26 7 14 21 28 4 11 18 25 2 9 16 23 30 6 13 20 27 1 8 15 22 29 5 12 19 26 3 10 17 24 31 7 14 21 28 2 9 16 23 30 6 13 20 27 4 11 18 25 1 8 15 22 29 6 13 20 27 4 11 18 25 1 8 15 22 29 6 13 20 27 7 14 21 28 5 12 19 26 2 9 16 23 30 7 14 21 28 1 8 15 22 29 6 13 20 27 3 10 17 24 1 8 15 22 29 2 9 16 23 30 7 14 21 28 4 11 18 25 2 9 16 23 30 3 10 17 24 1 8 15 22 29 5 12 19 26 3 10 17 24 31 4 11 18 25 2 9 16 23 30 6 13 20 27 4 11 18 25 5 12 19 26 3 10 17 24 31 7 14 21 28 5 12 19 26 |