Программа курса:
Разбор задачи: Зеркальное отражение
Предложенный нами код:
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
- На каждом шаге лазер поднимается или опускается на расстояние, равное
q, умноженное на направление движения. Еслиupравно 1, высота увеличивается. Еслиupравно минус 1, высота уменьшается. - Переменная
sideменяется после каждого шага. Это моделирует смену горизонтальной стороны комнаты. Если лазер был направлен вправо, он переходит к движению влево, и наоборот.
Проверка выхода за границы
Когда лазер достигает верхней или нижней границы комнаты, он "отражается". Это реализовано через проверку:
if h < 0:
h *= -1
up *= -1
- Если высота становится меньше нуля, лазер "ударяется" о нижнюю стену:
- Высота изменяется на положительное значение (берется модуль).
- Направление движения по вертикали меняется на противоположное (теперь лазер идет вверх).
elif h > p:
h = p - (h - p)
up *= -1
- Если высота превышает значение
p(верхняя стена), происходит следующее:- Высота корректируется. Если лазер "перелетает" через верхнюю стену, его избыточная высота "отражается" обратно. Например, если лазер достиг высоты 6 при
p = 5, его новая высота будет равна 4. - Направление движения по вертикали меняется (лазер теперь идет вниз).
- Высота корректируется. Если лазер "перелетает" через верхнюю стену, его избыточная высота "отражается" обратно. Например, если лазер достиг высоты 6 при
Проверка на попадание в угол
После каждого шага проверяется, достиг ли лазер одной из угловых точек:
if h % p == 0:
return h and side or 0
- Если текущая высота делится на
pбез остатка, это значит, что лазер находится либо в верхней, либо в нижней части комнаты:- Если высота равна нулю, лазер достиг нижнего левого угла. В этом случае возвращается 0.
- Если высота равна
p, возвращается значениеside, которое определяет горизонтальное положение:- Если
sideравно 2, лазер находится в верхнем правом углу. - Если
sideравно 1, лазер находится в верхнем левом углу.
- Если
Пример выполнения
Входные данные:
Сторона комнаты равна 5, а расстояние, на которое лазер перемещается за один шаг, равно 3.
Шаги алгоритма:
- Лазер стартует с высоты 0 и движется вверх на 3. Новая высота равна 3. Горизонтальное движение переходит вправо.
- Лазер снова движется вверх на 3. Новая высота равна 6. Она превышает максимальную высоту, поэтому происходит отражение:
- Избыточная высота 6 минус 5 равна 1. Отраженная высота становится равной 4.
- Лазер начинает двигаться вниз. Горизонтальное движение переходит влево.
- Лазер движется вниз на 3. Новая высота равна 1.
- Движение продолжается по описанным правилам до тех пор, пока лазер не достигнет одной из угловых точек.
Итог
Алгоритм завершится, когда лазер окажется в одном из углов комнаты. Возвращаемое значение показывает, где он остановился:
- 0 — нижний левый угол.
- 1 — верхний левый угол.
- 2 — верхний правый угол.