Даты

Структура — это переменная, которая сочетает в себе несколько независимых полей-переменных. Например, для представления даты необходимо три целых числа: день месяца, номер месяца, номер года. Удобно сделать комбинированный тип данных (называемый структурой), который является объединением трех целых переменных. Такой тип данных называется структурой и определяется так:

struct Date
{
    int day, month, year;
}

Здесь мы определили структуру данных Datе, которая состоит из трёх полей-переменных типа int: Day, Month, Year.

Теперь мы можем объявлять переменные типа Date, каждая такая переменная является объединением трех целочисленных переменных-полей. Для доступа к полю используется так называемая “dot-нотация” переменная.поле:

Date Today, Tomorrow;
Today.day = 23;
Today.month = 11;
Today.year = 2010;
Tomorrow = Today;
++Tomorrow.day;

В этом примере видно, что можно работать как целиком со структурой (например, присвоить целиком значение одной структуры другой структуре), так и с отдельными полями структуры.

Стуктуры можно передавать в функции по ссылке и по значению, можно использовать структуры, как возвращаемоей функцией значение, можно создавать массив структур и т.д. Для вывода названия месяца по его номеру лучше всего использовать константный массив строк-названий:

const string MonthNames[12]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
Для вывода названия дня недели лучше всего использовать константный массив строк-названий:
const string DayOfTheWeek[7]={"Monday", "Tuesday", "Wednesday",  "Thursday", "Friday", "Saturday", "Sunday"};

A: День года

По заданному числу n от 1 до 365 определите, на какое число какого месяца приходится день невисокосного года с номером n. Программа получает на вход целое число n и должна вывести два числа: число месяца (от 1 до 31) и номер месяца (от 1 до 12), на которое приходится данный день.
Алгоритм решения задачи оформите в виде отдельной функции
void MonthAndDayByNum(int n, string & month, int & day)
Параметры: n - номер дня в году (передается по значению, входные данные), month - номер месяца в году (результат работы алгоритма, передается по ссылке), day - номер дня в месяце (результат работы алгоритма, передается по ссылке).

На вход программа получает одно число от 1 до 365. Программа должна вывести ответ в формате "Месяц день" (через один пробел), где "Месяц" - название месяца по-английски с заглавной буквы, "день" - число от 1 до 31.

Для определения номера дня в году лучше всего использовать константный массив количества дней в каждом месяце:

const int Months[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

Пример

Ввод Вывод
1
January 1
365
December 31

B: Обратная задача

Решите обратную предыдущей задачу: по записи названия месяца и дня определите номер дня в году.
Алгоритм решения задачи оформите в виде отдельной функции.

Пример

Ввод Вывод
January 1
1
December 31
365

C: Перевод формата даты - 1

Дата задана в формате dd.mm.yyyy. Выведите ее в формате "Month d, y", где Month - английское название месяца, d - номер дня в месяце, без лидирующих нулей, y - номер года без лидирующих нулей. Алгоритмы считывания и вывода даты оформите в виде отдельных функций:
date ReadDDMMYYYYYY(string S)
void PrintString(date data)

Пример

Ввод Вывод
12.10.2008
October 12, 2008
01.01.0001
January 1, 1

D: Перевод формата даты - 2

Решите обратную задачу. Алгоритмы считывания и вывода даты оформите в виде отдельных функций:
date ReadString(string S)
void PrintDDMMYYYY(date data)

Пример

Ввод Вывод
October 12, 2008
12.10.2008
January 1, 1
01.01.0001

E: Tomorrow

Дата задана в формате dd.mm.yyyy. Выведите дату, следующую за ней в том же формате. Учтите правило формирования високосных годов. Следует считать, что григорианский календарь действовал всегда.
Алгоритм решения задачи оформите в виде функции date NextDate(date d)

Пример

Ввод Вывод
12.10.2008
13.10.2008
31.12.2008
01.01.2009

F: Yesterday

Дата задана в формате dd.mm.yyyy. Выведите дату, предшестующую ей в том же формате. Учтите правило формирования високосных годов. Следует считать, что григорианский календарь действовал всегда.
Алгоритм решения задачи оформите в виде функции date PrevDate(date d)

Пример

Ввод Вывод
13.10.2008
12.10.2008
01.01.2009
31.12.2008

G: Разница дат

Две даты заданы в формате dd.mm.yyyy, каждая дата - в новой строке. Определите количество дней между этими датами. Вторая дата больше первой.
Алгоритм решения задачи оформите в виде функции int DateDifference(date d1, date d2)

Пример

Ввод Вывод
01.01.0001
02.01.0001
1
29.02.2004
01.03.2005
366

H: День недели

Дата задана в формате dd.mm.yyyy. Выведите название дня недели, на который приходится эта дата.
Алгоритм решения задачи оформите в виде отдельной функции.
Ввод Вывод
12.10.2008
Sunday
13.10.2008
Monday

I: День рождения

Задан день и месяц рождения в формате dd.mm. Задана текущая дата в формате dd.mm.yyyy. Определите, сколько дней осталось до дня рождения. Если сегодня - день рождения, то необходимо вывести 0.

Ввод Вывод
19.04
19.04.2002
0
05.05
19.04.2002
16
29.02
28.02.2001
1096

J: Разница дат - 2

Научитесь быстро вычислять разницу между двумя датами.

Программа получает на вход число N, не превосходящее 105. Далее идет 2N дат, записанных, как в задаче G.

Выведите N чисел: для каждой пары дат входного файла выведите их разность.

Ввод Вывод
2
01.01.0001
02.01.0001
29.02.2004
01.03.2005
1
366

Время

Для хранения времени удобно завести структуру:

struct Time
{
    int hours;
    int minutes;
    int seconds;
};

Использовать для названия структуры идентификатор time нельзя, так как такое имя уже используется в стандартной библиотеке языка C++.

Времена будут, как правило, задаваться в формате hh:mm:ss, где hh принимает значения от 00 до 23, mm и ss - значения от 00 до 59 или в формате hh:mm.

K: Количество секунд

Часы показывают время в формате hh:mm:ss. Определите количество секунд, которое прошло с начала суток.
Программа не должна содержать циклов для решения этой задачи.

Пример

Ввод Вывод
00:01:01
61

L: Таймер

Часы показывают время в формате hh:mm:ss. На этих часах запустили таймер, который прозвенит через n секунд. Определите время, которое будет на часах, когда прозвенит таймер. n может принимать значения от 0 до 109. Решение задачи не дожно содержать циклов. Постарайтесь также не использовать условную инструкцию.

Пример

Ввод Вывод
09:00:00
90
09:01:30
23:59:59
1
00:00:00

M: Разница времен

Профессор лег спать, когда на часах было время h1:m1:s1, а когда он проснулся было время h2:m2:s2. Определите, сколько времени спал профессор, если известно, что он проспал не более суток. Время выведите в формате hh:mm:ss.
Решение задачи не должно содержать циклы. Постарайтесь также не использовать условную инструкцию.

Пример

Ввод Вывод
14:00:00
21:10:30
07:10:30
22:00:00
07:00:00
09:00:00

N: Севшая батарейка

В часах села батарейка и они стали идти вдвое медленней. Когда на часах было  время h1:m1:s1, точное время было h2:m2:s2. Определите, точное время, когда часы в следующий раз покажут время h3:m3:s3.
Решение задачи не должно использовать циклы.

Пример

Ввод Вывод
12:34:00
10:34:00
12:35:01
10:36:02
12:34:00
10:00:00
02:34:00
14:00:00

O: Будильники

Будильник в сотовом телефоне можно настроить так, чтобы он звонил каждый день в одно и то же время, либо в указанное время в определенный день недели. Независимо можно настроить несколько будильников.

По информации о будильниках и текущему времени и дню недели определите, когда прозвонит очередной будильник.

В первой строке вводится текущий день недели (число от 1 до 7), затем через пробел, текущее время в формате HH:MM.

Во второй строке вводится одно натуральное число N, не превосходящее 100 – количество будильников.

В следующих N строках вводится описание N будильников в таком же формате. Значение дня недели, равное 0, означает, что будильник звонит каждый день.

Выведите номер дня недели и время, когда будильник зазвонит в следующий раз, в таком же формате.

Ввод Вывод
2 10:20
2
1 23:15
0 10:10
3 10:10
7 01:01
3
7 00:59
7 23:59
7 01:01
7 01:01

P: Таймер-2

Таймер - это часы, которые умеют подавать звуковой сигнал по прошествии некоторого периода времени. Напишите программу, которая определяет, когда должен быть подан звуковой сигнал.

Первая строка входных данных содержит текущее время в формате 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
48:0:0
01:01:01+2 days
01:01:01
58:119
02:01:00
23:59:59
1
00:00:00+1 days

Q: Кассы

На одном из московских вокзалов билеты продают N касс. Каждая касса работает без перерыва определенный промежуток времени по фиксированному расписанию (одному и тому же каждый день). Требуется определить, на протяжении какого времени в течение суток работают все кассы одновременно.

Программа получает на вход целое число N (0<N≤1000).

В каждой из следующих N строк записано время начало и время окончания работы кассы в формате HH:MM через пробел.

Время открытия означает, что в соответствующую ему минуту касса уже работает, а время закрытия что в соответствующую минуту касса уже не работает. Например, касса, открытая с 10:30 18:30 ежесуточно работает 480 минут.

Если время открытия совпадает с временем закрытия, то касса работает круглосуточно. Если первое время больше второго, то касса начинает работу до полуночи, а заканчивает на следующий день.

Требуется вывести одно число суммарное время за сутки (в минутах), на протяжении которого работают все N касс.

Ввод Вывод
3
01:00 23:00
12:00 12:00
22:00 02:00
120
2
09:30 14:00
14:15 21:00
0
2
14:00 18:00
10:00 14:01
1

R: Самый старший

Имеется список людей с указанием их фамилии, имени и даты рождения. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять самого старшего человека из этого списка и выводить его фамилию, имя и дату рождения, а если имеется несколько самых старших людей с одинаковой датой рождения, то определять их количество.

На вход программе в первой строке подается количество людей в списке N. В каждой из последующих N строк находится информация в следующем формате:

<Фамилия> <Имя> <Дата рождения>

где <Фамилия> – строка, состоящая не более, чем из 20 символов без пробелов, <Имя> – строка, состоящая не более, чем из 20 символов без пробелов, <Дата рождения> – строка, имеющая вид DD.MM.YYYY.

Программа должна вывести дату рождения самого старшего человека в списке, затем через пробел его фамилию и имя. Если таких людей, несколько, то вместо фамилии и имени выводится их количество.

Ввод Вывод
3
Ivan Petrov 01.05.1995
Petr Sergeev 29.04.1995
Sergey Ivanov 01.01.1996
29.04.1995 Petr Sergeev
3
Ivan Petrov 01.05.1995
Petr Sergeev 29.05.1995
Sergey Ivanov 01.05.1995
01.05.1995 2

S: Дни рождения

Имеется список сотрудников организации с указанием их фамилии, имени и даты рождения. Администрация ежедневно поздравляет всех сотрудников, родившихся в этот день. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять, в какой из дней года родилось больше всего сотрудников и выводить этот день (или несколько дней).

Формат входных данных аналогичен предыдущей задаче. Программа должна вывести список дат, в которые наибольшее число сотрудников отмечает дни рождения в формате DD.MM по возрастанию дат, каждая дата в отдельной строке.

Ввод Вывод
5
Ivan Petrov 01.05.1995
Petr Sergeev 29.04.1995
Sergey Romanov 01.01.1996
Roman Grigoriev 01.01.1995
Grigoriy Ivanov 01.05.1995
01.01
01.05

T: Ближайшие дни рождения

Имеется список сотрудников организации с указанием их фамилии, имени и даты рождения. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять фамилию и имя самого молодого сотрудника, празднующего свой день рождения в течение ближайших семи дней от текущей даты (включая текущую дату).

На вход программе в первой сроке подается текущая дата, заданная в формате DD.MM.YYYY.

Во второй строке подается количество людей в списке N. В каждой из последующих N строк находится информация о каждом сотруднике, как в задаче T.

Известно, что у всех сотрудников даты рождения различаются. Программа должна вывести фамилию и имя самого молодого сотрудника, празднующего день рождения в ближайшие 7 дней или сообщение No birthdays in next week, если никто из сотрудников не празднует день рождения в ближайшие 7 дней.

Ввод Вывод
25.11.2010
3
Ivan Petrov 01.12.1994
Petr Sergeev 25.11.1994
Sergey Romanov 02.12.1994
Ivan Petrov
25.11.2010
1
Sergey Romanov 02.12.1994
No birthdays in next week

X: Пятница, 13-е

Докажите, что 13-е число месяца чаще всего приходится на пятницу.
Напишите программу, которая выводит на экран 7 чисел: вероятности выпадения 13 числа каждого месяца на понедельник, вторник, среду, четверг, пятницу, субботу, воскресенье. Например, если бы данные вероятности были бы равны, то программа должна вывести следущий текст:
0.142857
0.142857
0.142857
0.142857
0.142857
0.142857
0.142857

Y: Кассы - 2

Решите задачу про кассы в следующих ограничениях: число касс до 10000, время задано с точностью до секунд в формате HH:MM:SS. Требуется определить, на протяжении какого времени (в секундах) в течение суток работают все кассы одновременно.

Ввод Вывод
3
01:00:00 23:00:00
12:00:00 12:00:00
22:00:00 02:00:00
7200
2
09:30:00 14:00:00
14:15:00 21:00:00
0
2
14:00:00 18:00:00
10:00:00 14:00:01
1

Z: Игра с датами

Играет два человека. Задается какая-то дата високосного года. Каждый игрок на своем ходу называет более позднюю дату, увеличивая на 1 или на 2 либо день в месяце, либо месяц, но не то и другое сразу. При этом результат должен оставаться корректной датой. Игрок, назвавший 31 декабря, проигрывает. Кто выигрывает при правильной игре: первый или второй.

Программа получает на вход дату в формате DD.MM и должна вывести одно число: номер выигрывающего игрока.

Ввод Вывод
30.12
2
29.12
1
29.11
2