Новая Школа - онлайн-школа подготовки к ЕГЭ
Задача Задача №3519018
А
Аноним
27 ноября 2025 08:39 · публичный вопрос
А
Аноним

Робот-заборостроитель нагородил вертикальных заборов заборов между грядками на поле 7 на 7 клеток. Напишите для исполнителя Робот алгоритм движения до последней грядки. Врезаться…

Запрос пользователя

Робот-заборостроитель нагородил вертикальных заборов заборов между грядками на поле 7 на 7 клеток. Напишите для исполнителя Робот алгоритм движения до последней грядки. Врезаться в стены нельзя. Код должен сработать на всех пяти примерах. Старт и финиш всегда в левом верхнем и правом нижнем углах. Между соседними грядками (столбцами клеток) всегда есть один проход. Используйте Python и специальные функции робота. move_left() Сделать шаг влево move_right() Сделать шаг вправо move_up() Сделать шаг вверх move_down() Сделать шаг вниз wall_from_up() Проверить, есть ли стена сверху wall_from_down() Проверить, есть ли стена снизу wall_from_left() Проверить, есть ли стена слева wall_from_right() Проверить, есть ли стена справа

Ответ нейросети
27 ноября 2025 08:39

Ниже подробное решение и рабочий пример кода на Python. Задача: вести робота по сетке 7x7 от левого верхнего угла к правому нижнему, не врезаться в стены, используя доступные функции wall_from_... и move_... Так как между соседними грядками есть проход, путь существует для всех пяти примеров.

Что делаю и почему:

  • Использую обход в глубину (DFS) с возвратом (backtracking). Это простой и надёжный метод для лабиринтов, где мы можем двигаться только если нет стены слева/сверху и т.д.
  • В процессе хранения координат x,y мы поддерживаем начальную точку (0,0) и целевую точку (6,6).
  • Перед каждым ходом проверяю возможность движения через соответствующую функцию стены (например, для направления вправо проверяю wall_from_right и границы).
  • При движении обновляю координаты и помечаю клетку как посещённую. Когда наступает тупик, возвращаюсь обратно тем же путём (ресурсивно) через противоположное направление.
  • Приоритет движения направлен в сторону цели: сначала вправо, затем вниз, затем влево, затем вверх. Это ускоряет прохождение к цели, но алгоритм всё равно корректен и найдёт путь даже если приоритет не идеален.

Код (Python, с использованием заданных API робота):

# Предполагаемая размерность поля
WIDTH = 7
HEIGHT = 7

# Старт: (0, 0) - верхний левый угол
# Цель:  (6, 6) - нижний правый угол

# Список прямых направлений и соответствующих действий робота
# dx, dy для проверки координат, функции стены и движения
DIRECTIONS = [
    ("right",  1,  0, "move_right", "wall_from_right"),
    ("down",   0,  1, "move_down",  "wall_from_down"),
    ("left",  -1,  0, "move_left",  "wall_from_left"),
    ("up",     0, -1, "move_up",    "wall_from_up"),
]

def solve():
    start_x, start_y = 0, 0
    goal_x, goal_y = WIDTH - 1, HEIGHT - 1

    visited = set()
    visited.add((start_x, start_y))

    # Вспомогательная функция: можно ли сделать ход в заданном направлении
    def can_move(direction, x, y):
        if direction == "right":
            if x >= WIDTH - 1:
                return False
            # Проверка стены справа от текущей клетки
            return not wall_from_right()
        elif direction == "down":
            if y >= HEIGHT - 1:
                return False
            return not wall_from_down()
        elif direction == "left":
            if x <= 0:
                return False
            return not wall_from_left()
        elif direction == "up":
            if y <= 0:
                return False
            return not wall_from_up()
        return False

    # Преобразование направления в новое положение
    def move_dir(direction, x, y):
        if direction == "right":
            move_right()
            return x + 1, y
        if direction == "down":
            move_down()
            return x, y + 1
        if direction == "left":
            move_left()
            return x - 1, y
        if direction == "up":
            move_up()
            return x, y - 1
        return x, y

    # Преобразование направления в противоположное (для возврата назад)
    def opposite(direction):
        if direction == "right":  return "left"
        if direction == "left":   return "right"
        if direction == "down":   return "up"
        if direction == "up":     return "down"
        return None

    # Рекурсивный DFS
    def dfs(x, y):
        # Если достигли цели
        if x == goal_x and y == goal_y:
            return True

        # Порядок обхода: вправо, вниз, влево, вверх (приоритет к достижению цели)
        for dir_name, dx, dy, move_fn, wall_fn in DIRECTIONS:
            if can_move(dir_name, x, y):
                nx, ny = x + dx, y + dy
                if (nx, ny) not in visited:
                    # Сделать шаг
                    if dir_name == "right":
                        move_right()
                    elif dir_name == "down":
                        move_down()
                    elif dir_name == "left":
                        move_left()
                    elif dir_name == "up":
                        move_up()
                    else:
                        # на всякий случай (не должно срабатывать)
                        continue

                    visited.add((nx, ny))
                    if dfs(nx, ny):
                        return True
                    # Обратный ход назад (возврат к предыдущей клетке)
                    opp = opposite(dir_name)
                    if opp == "right":
                        move_right()
                    elif opp == "down":
                        move_down()
                    elif opp == "left":
                        move_left()
                    elif opp == "up":
                        move_up()
                    # Примечание: не снимаем клетку из visited, чтобы не зацикливаться
        return False

    # Запуск поиска
    dfs(start_x, start_y)

# Вызов
solve()

Пояснения по коду:

  • WIDTH и HEIGHT заданы как 7, чтобы соответствовать полю 7x7.
  • visited хранит посещённые клетки и не позволяет повторно входить в них, что исключает бесконечные циклы.
  • can_move учитывает границы поля и наличие стены с помощью wall_from_* функций.
  • При движении вызываются соответствующие функции move_*, а после достижения новой клетки рекурсивно продолжается поиск.
  • При тупике выполняется возврат через противоположное направление (backtracking).

Как это поможет на всех пяти примерах:

  • Гарантированная возможность пройти от (0,0) до (6,6) в условиях “между соседними грядками есть проход” обеспечивает наличие пути. DFS с возвратом найдёт этот путь независимо от конкретной конфигурации стен внутри поля.
  • Приоритет направлений помогает быстрее выбрать путь к финишу, но в любом случае путь будет найден благодаря проверке wall_from_* и границ поля.

Если потребуется адаптация под другой размер поля (например, 5x5 или 10x10):

  • поменяйте WIDTH и HEIGHT на нужные значения.
  • при необходимости можно изменить порядок направлений в DIRECTIONS для другого поведения движения.