Разбор задачи: Области, разрезанные косыми чертами

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

 def regionsBySlashes(grid):
        def dfs(i, j, k):
            if 0 <= i < n > j >= 0 and not matrix[i][j][k]:
                if grid[i][j] == "*":
                    if k <= 1:
                        matrix[i][j][0] = matrix[i][j][1] = cnt
                        dfs(i - 1, j, 2)
                        dfs(i, j + 1, 3)
                    else:
                        matrix[i][j][2] = matrix[i][j][3] = cnt
                        dfs(i + 1, j, 0)
                        dfs(i, j - 1, 1)
                elif grid[i][j] == "/":
                    if 1 <= k <= 2:
                        matrix[i][j][1] = matrix[i][j][2] = cnt
                        dfs(i, j + 1, 3)
                        dfs(i + 1, j, 0)
                    else:
                        matrix[i][j][0] = matrix[i][j][3] = cnt
                        dfs(i - 1, j, 2)
                        dfs(i, j - 1, 1)
                else:
                    matrix[i][j][0] = matrix[i][j][1] = matrix[i][j][2] = matrix[i][j][3] = cnt
                    dfs(i - 1, j, 2)
                    dfs(i, j + 1, 3)
                    dfs(i + 1, j, 0)
                    dfs(i, j - 1, 1)
        grid, n = [row.replace("\u005C\u005C", "*") for row in grid], len(grid)
        matrix, cnt = [[[0, 0, 0, 0] for j in range(n)] for i in range(n)], 0
        for i in range(n):
            for j in range(n):
                for k in range(4):
                    if not matrix[i][j][k]:
                        cnt += 1
                        dfs(i, j, k)
        return cnt

Данная функция regionsBySlashes решает задачу подсчета количества регионов, которые формируются на сетке, разделенной символами '/', '\\' (обозначенными как '*'), и пробелами ' '. В основе решения лежит использование DFS (поиск в глубину) для подсчета соединенных регионов. Рассмотрим код по частям:


1. Преобразование символов в сетке

grid = [row.replace("\u005C\u005C", "*") for row in grid]
n = len(grid)
  • Символ '\\' в задаче представлен как "\u005C\u005C". На этом этапе мы заменяем его на '*' для упрощения работы с символами.
  • Переменная n определяет размер сетки.

2. Инициализация матрицы и счетчика регионов

matrix = [[[0, 0, 0, 0] for j in range(n)] for i in range(n)]
cnt = 0
  • matrix — это трехмерный массив, где каждая ячейка сетки делится на четыре части (в зависимости от направления: верх, право, низ, лево). Каждую часть представляют элементы списка [0, 0, 0, 0].
  • cnt — счетчик, который увеличивается каждый раз, когда мы находим новый регион.

3. Рекурсивная функция DFS

def dfs(i, j, k):
    if 0 <= i < n > j >= 0 and not matrix[i][j][k]:
        ...
  • Проверяется, находится ли текущая ячейка внутри границ сетки и была ли текущая часть ячейки уже посещена.
  • Если ячейка или ее часть еще не посещены, мы помечаем их, используя текущий номер региона cnt.

4. Обработка ячейки в зависимости от символа

Ячейка с символом '*':

if grid[i][j] == "*":
    if k <= 1:  # Обработка верхней и правой частей
        matrix[i][j][0] = matrix[i][j][1] = cnt
        dfs(i - 1, j, 2)  # Проверяем верхнюю ячейку
        dfs(i, j + 1, 3)  # Проверяем правую ячейку
    else:  # Обработка нижней и левой частей
        matrix[i][j][2] = matrix[i][j][3] = cnt
        dfs(i + 1, j, 0)  # Проверяем нижнюю ячейку
        dfs(i, j - 1, 1)  # Проверяем левую ячейку
  • Если текущая ячейка содержит символ '*' (аналог '\''), она делится на верхние и нижние части. Для каждой части вызываются DFS, чтобы проверить соседние ячейки.

Ячейка с символом '/':

elif grid[i][j] == "/":
    if 1 <= k <= 2:  # Обработка правой и нижней частей
        matrix[i][j][1] = matrix[i][j][2] = cnt
        dfs(i, j + 1, 3)  # Проверяем правую ячейку
        dfs(i + 1, j, 0)  # Проверяем нижнюю ячейку
    else:  # Обработка верхней и левой частей
        matrix[i][j][0] = matrix[i][j][3] = cnt
        dfs(i - 1, j, 2)  # Проверяем верхнюю ячейку
        dfs(i, j - 1, 1)  # Проверяем левую ячейку
  • Символ '/' делит ячейку на две диагональные части. Например, если обрабатывается верхняя часть, то соседние клетки, которые могут быть частью текущего региона, находятся сверху и слева.

Ячейка с пробелом ' ':

else:
    matrix[i][j][0] = matrix[i][j][1] = matrix[i][j][2] = matrix[i][j][3] = cnt
    dfs(i - 1, j, 2)  # Проверяем верхнюю ячейку
    dfs(i, j + 1, 3)  # Проверяем правую ячейку
    dfs(i + 1, j, 0)  # Проверяем нижнюю ячейку
    dfs(i, j - 1, 1)  # Проверяем левую ячейку
  • Пробел ' ' означает, что вся ячейка принадлежит одному региону. В этом случае все четыре части помечаются как посещенные.

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

for i in range(n):
    for j in range(n):
        for k in range(4):
            if not matrix[i][j][k]:
                cnt += 1
                dfs(i, j, k)
  • Здесь происходит обход каждой ячейки и каждой ее части. Если текущая часть еще не была посещена, мы начинаем новый поиск DFS, увеличивая счетчик регионов cnt.

Итоговый результат

return cnt
  • После завершения всех обходов возвращается общее количество регионов cnt.

Заключение

Это решение основано на преобразовании каждой ячейки в сетке в четыре части для более точного учета регионов. Использование рекурсии (DFS) позволяет эффективно подсчитывать соединенные области, формирующие регионы.

 


0

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