Ниже подробное решение задачи: как сделать так, чтобы робот переходил к следующей по часовой стрелке нише (клетке) на периметре прямоугольного зала и покрашивал её. В конце — рабочий пример кода на Python и пояснения.
Цель и подход
- Что считаем нишами: все клетки вдоль периметра прямоугольника шириной w и высотой h. Внутренние клетки не рассматриваем.
- Ниши обходят по часовой стрелке: сверху слева направо, далее вправо по правой стороне вниз, по нижней стороне слева, по левой стороне вверх.
- Робот начинает в начальной нише (обычно в углу, например (0,0)) и на каждой новой нише красит её. Для хода к следующей нише используется правило перехода по периметру.
Алгоритм (пошагово)
- Задать размеры зала: ширину w и высоту h. Определить стартовую клетку на периметре (например (0,0)).
- Функция next_clockwise(x, y, w, h) возвращает координаты следующей по часовой стрелке клетки на периметре:
- если y == 0 и x < w-1: переход к (x+1, 0)
- иначе если x == w-1 и y < h-1: переход к (w-1, y+1)
- иначе если y == h-1 и x > 0: переход к (x-1, h-1)
- иначе если x == 0 и y > 0: переход к (0, y-1)
- для особых случаев (одна строка или один столбец) правило всё равно корректно описывает переход по периметру, с возможной повторной петлей, если он нужен.
- Переход к следующей нише: вычислить следующую пару координат, затем покрасить новую нишу (если ещё не покрашена).
- Повторять, пока не покроем все периметральные ниши. Число ниш на периметре равно:
- если w==1 и h==1: 1
- если w==1: h
- если h==1: w
- иначе 2w + 2h - 4
- Временная сложность: O(N), где N — число ниш на периметре.
Простой вариант на Python (вариант 1: без предварительного списка периметра, по правилу перехода)
- Этот код моделирует робота как простого штурмана по периметру и возвращает порядок посещения и раскраски ниш.
Python (вариант 1: ход по правилу next_clockwise)
def perimeter_count(w, h): if w == 1 and h == 1: return 1 if w == 1: return h if h == 1: return w return 2 * w + 2 * h - 4
def next_clockwise(x, y, w, h): # Порядок обхода по периметру в направлении по часовой стрелке if w == 1 and h == 1: return (0, 0) if y == 0 and x < w - 1: return (x + 1, y) if x == w - 1 and y < h - 1: return (x, y + 1) if y == h - 1 and x > 0: return (x - 1, y) if x == 0 and y > 0: return (0, y - 1) # Безопасная заготовка на случай необычных конфигураций return (0, 0)
def traverse_perimeter(width, height, start=(0, 0)): w, h = width, height x, y = start coords_path = [(x, y)] painted = {(x, y)} total = perimeter_count(w, h)
for _ in range(total - 1):
nx, ny = next_clockwise(x, y, w, h)
coords_path.append((nx, ny))
painted.add((nx, ny))
x, y = nx, ny
return coords_path, painted
Пример использования
if name == "main": w, h = 6, 4 # размеры зала path, painted = traverse_perimeter(w, h, start=(0, 0)) print("Путь по нишам (координаты):", path) print("Всего ниш покрашено:", len(painted))
Пояснение к variant 1
- start задаёт начальную нишу на периметре, здесь (0,0).
- Функция next_clockwise реализует переход к следующей нише по часовой стрелке: вдоль верхней стороны вправо, затем вниз по правой стороне, затем влево по нижней, затем вверх по левой.
- В цикле мы добавляем каждую нишу в путь и помечаем её как покрашенную. Целевое число ниш на периметре определяется функцией perimeter_count.
Простой вариант на Python (вариант 2: через явный список периметра)
- Сначала формируем полный список ниш по часовой стрелке, затем просто идём по нему по циклу.
Python (вариант 2: явный список периметра)
def perimeter_coords(width, height): coords = [] w, h = width, height if w <= 0 or h <= 0: return coords # верхняя граница for x in range(w): coords.append((x, 0)) # правая граница (без угла сверху) for y in range(1, h): coords.append((w - 1, y)) # нижняя граница (без угла справа) if h > 1: for x in range(w - 2, -1, -1): coords.append((x, h - 1)) # левая граница (без нижнего и верхнего углов) if w > 1: for y in range(h - 2, 0, -1): coords.append((0, y)) return coords
def traverse_with_list(width, height, start_index=0): coords = perimeter_coords(width, height) if not coords: return [] N = len(coords) idx = start_index % N path = [] painted = set() for i in range(N): cell = coords[(idx + i) % N] path.append(cell) painted.add(cell) return path, painted
Пример использования
if name == "main": w, h = 6, 4 path, painted = traverse_with_list(w, h, start_index=0) print("Путь по нишам (координаты):", path) print("Всего ниш покрашено:", len(painted))
Что выбрать и как адаптировать
- Если нужно просто понять алгоритм обхода и проверить логику — можно начать с варианта 2 (явный список периметра). Он нагляден и легко расширяется.
- Если нужно моделировать поведение в реальном роботе (последовательно двигаться и окрашивать каждую нишу в реальном времени), лучше вариант 1 (движение по правилу next_clockwise) — он ближе к шагам движения робота и позволяет легко добавлять «скачки» состояния и действия.
Пример применения и результаты
- Пусть w = 6, h = 4. Периметр содержит N = 2w + 2h - 4 = 26 + 24 - 4 = 16 ниш.
- Запустив любой из вариантов, мы получим последовательность из 16 координат вдоль периметра, начиная с (0,0) и возвращаясь к началу после последней ниши, если цикл повторяется.
Расширения и замечания
- Можно начать с любой начальной клетки на периметре, просто найти её индекс в списке coords и начать обход оттуда.
- Если нужно пометить каждую нишу не просто как посещённую, а с цветом покраски, можно хранить в массиве/словаре цвет каждого элемента.
- Если зал может иметь нестандартную форму (например, в некоторых нишах могут быть выступы), потребуются дополнительные проверки на принадлежность клетки к периметру и корректный способ перехода.
Если скажете язык программирования и конкретный формат входных данных/начальных условий (например, стартовую нишу или координаты начала, размер зала), могу привести адаптированную версию к вашему контексту или сделать минимальный скрипт, который можно запустить у вас на компьютере.