Редакция для Парковка


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Автор: montes332

1. Идея

Для каждого запроса нужно:

  1. перевести время въезда и выезда в минуты от начала суток;
  2. найти длительность стоянки в минутах;
  3. округлить её вверх до целого числа часов;
  4. по количеству оплаченных часов посчитать цену по тарифу.

Задача сводится к аккуратной реализации нескольких простых шагов.


2. Наблюдения

1. Время удобно хранить в минутах

Строка вида HH:MM легко переводится в число минут:

  • часы: HH
  • минуты: MM
  • всего минут от начала суток: HH * 60 + MM

Например:

  • 10:00 -> 600
  • 10:01 -> 601

Тогда длительность парковки равна просто разности:

d = finish - start

2. Нужно округление вверх до часов

Если машина стояла:

  • 1 минуту, оплачивается 1 час;
  • 60 минут, тоже 1 час;
  • 61 минуту, уже 2 часа.

Это классическое округление вверх:

h = (d + 59) // 60

Почему так работает:

  • для d = 1..60 получаем 1;
  • для d = 61..120 получаем 2;
  • и так далее.

3. Тариф кусочный

Стоимость зависит от числа оплаченных часов h.

  • если h = 1, то цена 100;
  • если 2 <= h <= 5, то:
    • первый час стоит 100,
    • остальные h - 1 часов по 80;
  • если h >= 6, то:
    • первый час 100,
    • со 2-го по 5-й: 4 часа по 80,
    • остальные h - 5 часов по 50.

3. Алгоритм

Для каждого запроса:

  1. считать строки t1 и t2;
  2. перевести t1 в минуты:
    • hh1 = int(t1[0:2])
    • mm1 = int(t1[3:5])
    • m1 = hh1 * 60 + mm1
  3. аналогично перевести t2 в m2;
  4. найти длительность: d = m2 - m1;
  5. найти число оплаченных часов:
    • h = (d + 59) // 60
  6. посчитать стоимость:
    • если h == 1, ответ 100;
    • иначе если h <= 5, ответ 100 + (h - 1) * 80;
    • иначе ответ 100 + 4 * 80 + (h - 5) * 50;
  7. вывести ответ.

4. Почему это работает

Докажем корректность по шагам.

Перевод времени в минуты

Момент времени HH:MM содержит HH полных часов и MM минут после них.
Значит, количество минут от начала суток равно HH * 60 + MM.

Следовательно, если въезд был в момент m1, а выезд — в момент m2, то длительность стоянки в минутах равна m2 - m1. По условию t1 < t2, поэтому длительность всегда положительна.

Округление вверх до часов

Оплачиваемое число часов должно быть равно:

  • 1, если стоянка длилась от 1 до 60 минут;
  • 2, если от 61 до 120 минут;
  • ...

Формула h = (d + 59) // 60 именно это и делает:

  • если d делится на 60, получаем точное число часов;
  • если не делится, добавление 59 переносит результат к следующему целому часу.

Значит, h — это длина стоянки в часах с округлением вверх, как и требуется.

Подсчёт тарифа

Дальше остаётся точно следовать условию:

  • первый оплаченный час всегда стоит 100;
  • часы со 2-го по 5-й стоят по 80;
  • начиная с 6-го — по 50.

Разбор по случаям:

  1. h == 1
    Есть только первый час, цена 100.

  2. 2 <= h <= 5
    Первый час: 100,
    ещё h - 1 часов по 80,
    итого 100 + (h - 1) * 80.

  3. h >= 6
    Первый час: 100,
    4 часа со 2-го по 5-й: 4 * 80,
    ещё h - 5 часов по 50,
    итого 100 + 4 * 80 + (h - 5) * 50.

Все варианты числа часов покрыты, значит алгоритм всегда выдаёт правильную стоимость.


5. Сложность

Для каждого запроса выполняется константное число операций.

  • Время на один запрос: O(1)
  • Общее время: O(q)
  • Дополнительная память: O(1)

Это легко укладывается в ограничения даже при q = 10^5.


6. Код на C++17

#include <iostream>
#include <string>

using namespace std;

int to_minutes(const string& s) {
    int hh = (s[0] - '0') * 10 + (s[1] - '0');
    int mm = (s[3] - '0') * 10 + (s[4] - '0');
    return hh * 60 + mm;
}

int main() {
    int q;
    cin >> q;

    for (int i = 0; i < q; i++) {
        string t1, t2;
        cin >> t1 >> t2;

        int m1 = to_minutes(t1);
        int m2 = to_minutes(t2);
        int d = m2 - m1;
        int h = (d + 59) / 60;

        int cost;
        if (h == 1) {
            cost = 100;
        } else if (h <= 5) {
            cost = 100 + (h - 1) * 80;
        } else {
            cost = 100 + 4 * 80 + (h - 5) * 50;
        }

        cout << cost << "\n";
    }

    return 0;
}

7. Код на Python 3

q = int(input())

for _ in range(q):
    t1, t2 = input().split()

    h1 = int(t1[:2])
    m1 = int(t1[3:])
    h2 = int(t2[:2])
    m2 = int(t2[3:])

    start = h1 * 60 + m1
    finish = h2 * 60 + m2
    d = finish - start
    h = (d + 59) // 60

    if h == 1:
        cost = 100
    elif h <= 5:
        cost = 100 + (h - 1) * 80
    else:
        cost = 100 + 4 * 80 + (h - 5) * 50

    print(cost)

Комментарии

Еще нет ни одного комментария.