Добавить в корзинуПозвонить
Найти в Дзене
Анастасия Софт

Решение задачи о королевах на языке программирования Python

Задача о королевах — это классическая задача в теории графов, которая зачастую встречается на различных олимпиадах, соревнованиях по программированию и даже в фильмах, где математики пытаются решить сверхсложные проблемы. Если вас интересует, как можно решить эту задачу с помощью Python, то добро пожаловать в мир битв за шахматные клетки, где царствуют не пехотинцы, а королевы. Задача заключается в том, чтобы расставить N королев на шахматной доске размером N x N так, чтобы они не угрожали друг другу. В шахматах королева может двигаться по вертикали, горизонтали и диагоналям, поэтому важно найти такое положение королев, чтобы они не попадали под "удар" друг друга. В случае с задачей о королевах мы должны найти все возможные уникальные расставления королев, которые не угрожают друг другу. Это классическая задача на поиски решений с возвратом (backtracking), которая учит нас думать на несколько шагов вперед (и потом отступать, если что-то пошло не так). Для начала, давайте подумаем, как
Оглавление

Задача о королевах — это классическая задача в теории графов, которая зачастую встречается на различных олимпиадах, соревнованиях по программированию и даже в фильмах, где математики пытаются решить сверхсложные проблемы. Если вас интересует, как можно решить эту задачу с помощью Python, то добро пожаловать в мир битв за шахматные клетки, где царствуют не пехотинцы, а королевы.

Итоговая расстановка королев на доске.
Итоговая расстановка королев на доске.

В чем суть задачи?

Задача заключается в том, чтобы расставить N королев на шахматной доске размером N x N так, чтобы они не угрожали друг другу. В шахматах королева может двигаться по вертикали, горизонтали и диагоналям, поэтому важно найти такое положение королев, чтобы они не попадали под "удар" друг друга.

В случае с задачей о королевах мы должны найти все возможные уникальные расставления королев, которые не угрожают друг другу. Это классическая задача на поиски решений с возвратом (backtracking), которая учит нас думать на несколько шагов вперед (и потом отступать, если что-то пошло не так).

Как решать?

Для начала, давайте подумаем, как можно реализовать решение с использованием Python. Нам нужно следить за тем, какие клетки заняты, и как королевы могут угрожать друг другу. И, разумеется, будем использовать рекурсию, чтобы поэтапно строить решение.

Шаги:

  1. Создаем шахматную доску.
  2. Пытаемся разместить королев по одной в каждом ряду.
  3. Для каждой королевы проверяем, не угрожает ли она другим, проверяя вертикаль, горизонталь и диагонали.
  4. Если решение найдено, сохраняем его, если нет — отходим и пробуем другое расположение.

Теперь давайте погрузимся в код.

Код на Python

def is_safe(board, row, col, n):
# Функция проверяет, безопасно ли поставить королеву в клетку (row, col)

# Проверяем, нет ли королевы в той же колонке (индекс колонки сохраняется в board[i])
for i in range(row): # Идем по всем уже размещенным королевам
if board[i] == col or \ # Проверка по колонке
board[i] - i == col - row or \ # Проверка по диагонали (левая диагональ)
board[i] + i == col + row: # Проверка по диагонали (правая диагональ)
return False # Если есть угроза, возвращаем False
return True # Если угроз нет, возвращаем True

def solve_n_queens(n):
# Главная функция для решения задачи о королевах

board = [-1] * n # Инициализируем пустую доску размером n x n (каждая королева еще не размещена)
results = [] # Список для хранения всех найденных решений

# Вспомогательная рекурсивная функция для поиска решений
def solve(row):
# Если мы разместили королев во всех рядах, то нашли одно решение
if row == n:
results.append(board[:]) # Добавляем решение в список (копируем текущее состояние доски)
return

# Пробуем разместить королеву в каждом столбце текущего ряда
for col in range(n):
if is_safe(board, row, col, n): # Если безопасно разместить королеву в текущей клетке
board[row] = col # Размещаем королеву в этой клетке
solve(row + 1) # Рекурсивно пытаемся разместить королеву в следующем ряду
board[row] = -1 # Откатываемся (удаляем королеву), пробуем следующую клетку

solve(0) # Начинаем решение с первого ряда
return results # Возвращаем все найденные решения

def print_solution(board):
# Функция для печати одного решения в виде шахматной доски

n = len(board) # Размер доски
for i in range(n):
# Строим строку для ряда: если столбец совпадает с позицией королевы, ставим "Q", иначе "."
row = ['Q' if j == board[i] else '.' for j in range(n)]
print(" ".join(row)) # Выводим ряд

# Пример использования
n = 8 # Размер доски (количество королев)
solutions = solve_n_queens(n) # Получаем все решения для 8 королев

# Выводим количество решений
print(f"Найдено решений для {n} королев: {len(solutions)}\n")

# Выводим каждое решение
for solution in solutions:
print_solution(solution) # Печатаем доску для каждого решения
print("\n" + "="*20 + "\n") # Разделитель между решениями

Разбор кода:

  1. Функция is_safe:
    Эта функция проверяет, безопасно ли ставить королеву в клетку на позиции (row, col). Для этого она проверяет три вещи:
    Колонку: если в той же колонке уже стоит королева, то нельзя ставить еще одну.
    Диагонали: королевы не могут быть на одной диагонали (слева и справа от текущей позиции).
    Если одно из этих условий нарушается, функция возвращает False. В противном случае — True.
  2. Функция solve_n_queens:
    Основная рекурсивная функция, которая решает задачу о королевах.
    Мы пытаемся разместить королеву в каждом ряду и проверяем, не угрожает ли она другим королевам с помощью функции is_safe.
    Если удается разместить королеву в ряду, мы рекурсивно пробуем разместить королеву в следующем ряду.
    Когда все ряды заполнились (условие row == n), мы добавляем текущее расположение королев в список results.
    Если королева не может быть размещена в текущем ряду, происходит "откат" (удаляем королеву и пробуем следующее возможное положение).
  3. Функция print_solution:
    Эта функция принимает одно решение (расположение королев на доске) и выводит его в виде шахматной доски, где "Q" означает королеву, а "." — пустую клетку.
  4. Основной блок кода:
    Мы устанавливаем размер доски (n = 8 для классической задачи о 8 королевах).
    Вызываем функцию solve_n_queens для нахождения всех решений.
    Печатаем количество найденных решений и каждое решение в виде шахматной доски.

Пример вывода для 8 королев:

Найдено решений для 8 королев: 92

Q . . . . . . .
. . . . Q . . .
. . . . . . Q .
. . Q . . . . .
. . . . . Q . .
. Q . . . . . .
. . . Q . . . .
. . . . . . . Q

====================

. . . . . . . Q
. . . . . Q . .
. . . . Q . . .
. . . Q . . . .
. Q . . . . . .
. . Q . . . . .
Q . . . . . . .
. . . . . . Q .

====================
... и так далее для других решений

Каждое решение будет выглядеть как шахматная доска, где "Q" будет указывать на расположение королев, а "." — на пустую клетку.

Надеюсь, это поможет вам лучше понять решение задачи!

В чем магия?

Каждое решение задачи о королевах — это уникальная расстановка королев, где они не угрожают друг другу. В задаче с 8 королевами (классическая задача) существует 92 различных решения. Важно заметить, что решения различаются не только по расположению королев на доске, но и по симметрии (повороты и зеркальные отражения не считаются уникальными решениями).

Немного юмора

А теперь давайте немножко отвлечемся от серьёзных вычислений. В конце концов, если вы когда-нибудь решите задачу о королевах, не забудьте, что королева на доске — это не просто персонаж, она еще и стратег, и психолог! Она всегда находит решение, даже если где-то внутри нас живет сомнение в её силах. Но помните, как в шахматах, так и в программировании — важно не только поставить правильные фигуры, но и делать правильные ходы!

С помощью Python мы решили эту задачу, но на деле это тоже битва с собой — вы всегда можете "переместить" одну королеву и увидеть, что решение уже совсем другое.

Ну а если вдруг в следующий раз королева откажется от ваших планов, просто скажите: «Это не ошибка, это возможность для улучшения!» 😉

Заключение

Задача о королевах — это замечательная тренировка для мышления и умения решать задачи с возвратом. В Python она становится особенно удобной благодаря простоте реализации и мощной поддержке рекурсии. Так что, если вы хотите развивать свои навыки, эта задача — отличный старт!

И помните: в мире королев не бывает мелочей. Каждое ваше движение на доске важно!

Решение задачи о королевах на языке программирования Python, уроки программирования для начинающих и продолжающих
Решение задачи о королевах на языке программирования Python, уроки программирования для начинающих и продолжающих