Разбор задачи: Зеркальное отражение

Предложенный нами код:

 def findReceptor(p, q):
        side, up, h = 2, 1, 0
        while True:
            h += q * up
            side = (side + 1) % 2
            if side == 0:
                side += 2
            if h < 0:
                h *= -1
                up *= -1
            elif h > p:
                h = p - (h - p)
                up *= -1
            if h % p == 0:
                return h and side or 0

Дано квадратное помещение с длиной стороны p. Лазер начинает движение из левого нижнего угла комнаты под углом вверх и вправо. Лазер может отражаться от стен, потолка и пола. Нужно определить, в каком углу комнаты он остановится: верхнем правом, верхнем левом или нижнем правом.


Инициализация переменных

side, up, h = 2, 1, 0
  • Переменная side определяет, в какую сторону лазер движется по горизонтали. Если значение равно 2, лазер движется вправо. Если равно 1, то влево.
  • Переменная up показывает, куда движется лазер по вертикали. Если значение равно 1, лазер движется вверх. Если равно минус 1, то вниз.
  • Переменная h определяет текущую высоту лазера относительно нижней стены комнаты. В начале лазер стартует с высоты 0.

Основной цикл

Лазер движется, пока не достигнет одной из угловых точек. Это реализовано в цикле:

while True:
    h += q * up
    side = (side + 1) % 2
    if side == 0:
        side += 2
  1. На каждом шаге лазер поднимается или опускается на расстояние, равное q, умноженное на направление движения. Если up равно 1, высота увеличивается. Если up равно минус 1, высота уменьшается.
  2. Переменная side меняется после каждого шага. Это моделирует смену горизонтальной стороны комнаты. Если лазер был направлен вправо, он переходит к движению влево, и наоборот.

Проверка выхода за границы

Когда лазер достигает верхней или нижней границы комнаты, он "отражается". Это реализовано через проверку:

if h < 0:
    h *= -1
    up *= -1
  • Если высота становится меньше нуля, лазер "ударяется" о нижнюю стену:
    1. Высота изменяется на положительное значение (берется модуль).
    2. Направление движения по вертикали меняется на противоположное (теперь лазер идет вверх).
elif h > p:
    h = p - (h - p)
    up *= -1
  • Если высота превышает значение p (верхняя стена), происходит следующее:
    1. Высота корректируется. Если лазер "перелетает" через верхнюю стену, его избыточная высота "отражается" обратно. Например, если лазер достиг высоты 6 при p = 5, его новая высота будет равна 4.
    2. Направление движения по вертикали меняется (лазер теперь идет вниз).

Проверка на попадание в угол

После каждого шага проверяется, достиг ли лазер одной из угловых точек:

if h % p == 0:
    return h and side or 0
  • Если текущая высота делится на p без остатка, это значит, что лазер находится либо в верхней, либо в нижней части комнаты:
    • Если высота равна нулю, лазер достиг нижнего левого угла. В этом случае возвращается 0.
    • Если высота равна p, возвращается значение side, которое определяет горизонтальное положение:
      • Если side равно 2, лазер находится в верхнем правом углу.
      • Если side равно 1, лазер находится в верхнем левом углу.

Пример выполнения

Входные данные:

Сторона комнаты равна 5, а расстояние, на которое лазер перемещается за один шаг, равно 3.

Шаги алгоритма:

  1. Лазер стартует с высоты 0 и движется вверх на 3. Новая высота равна 3. Горизонтальное движение переходит вправо.
  2. Лазер снова движется вверх на 3. Новая высота равна 6. Она превышает максимальную высоту, поэтому происходит отражение:
    • Избыточная высота 6 минус 5 равна 1. Отраженная высота становится равной 4.
    • Лазер начинает двигаться вниз. Горизонтальное движение переходит влево.
  3. Лазер движется вниз на 3. Новая высота равна 1.
  4. Движение продолжается по описанным правилам до тех пор, пока лазер не достигнет одной из угловых точек.

Итог

Алгоритм завершится, когда лазер окажется в одном из углов комнаты. Возвращаемое значение показывает, где он остановился:

  • 0 — нижний левый угол.
  • 1 — верхний левый угол.
  • 2 — верхний правый угол.

 


0

Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии