Bài toán 8 hậu (Đề thi Tin học trẻ)

Bài toán 8 hậu (Đề thi Tin học trẻ năm 2000)

Trên bàn cờ vua hãy sẵp xếp đúng 8 quân Hậu sao cho không còn con nào có thể ăn được con nào. Hãy tìm ra nhiều cách sắp nhất?

Đây là một bài toán nổi tiếng trong lý thuyết đồ thị và cũng là một bài toán có tính thực tiễn cao trong lĩnh vực trí tuệ nhân tạo, vì nó liên quan đến vấn đề tối ưu hóa và kiến thức về cấu trúc dữ liệu đồ thị. Ngoài ra, bài toán 8 quân Hậu cũng có nhiều ứng dụng trong các lĩnh vực khác như trò chơi cờ vua, mật mã học và kiến thức máy tính. Hy vọng câu trả lời trên đã giúp bạn hiểu về bài toán 8 quân Hậu trên bàn cờ vua

Lời giải Bài toán 8 hậu

Dưới đây là một số cách sắp xếp đúng 8 quân Hậu trên bàn cờ vua sao cho không có quân nào có thể ăn được quân nào. Các cách này đều là cách sắp xếp tối ưu về mặt số lượng động thái cần di chuyển để đạt được kết quả đúng:

Cách 1:

H . . . . . . .
. . H . . . . .
. . . . H . . .
. . . . . . H .
. H . . . . . .
. . . H . . . .
. . . . . H . .
. . . . H . . .

Cách 2:

. H . . . . . .
. . . H . . . .
H . . . . . . .
. . . . H . . .
. . H . . . . .
. . . . . H . .
. . . H . . . .
. H . . . . . .

Cách 3:

. . . H . . . .
H . . . . . . .
. . H . . . . .
. . . . . H . .
. H . . . . . .
. . . . H . . .
. . . . . . H .
. . H . . . . .

Cách 4:

. . H . . . . .
. H . . . . . .
. . . H . . . .
H . . . . . . .
. . . . H . . .
. . H . . . . .
. . . . . H . .
. H . . . . . .

Đây là chỉ là 4 cách trong tổng cộng 12 cách sắp xếp đúng 8 quân Hậu trên bàn cờ vua sao cho không có quân nào có thể ăn được quân nào. Các cách này đều là những cách tối ưu về số lượng động thái cần di chuyển và được chấp nhận là đáp án chính xác cho bài toán 8 quân Hậu trên bàn cờ vua. Ở đây, ký hiệu “H” đại diện cho quân Hậu, và dấu chấm (“.”) đại diện cho các ô trống trên bàn cờ vua. Mỗi cách sắp xếp này đảm bảo rằng không có quân nào có thể ăn được quân nào, theo các quy tắc chơi cờ vua. Chúc bạn thành công trong việc giải quyết bài toán này! Bạn cũng có thể thử tìm kiếm các phương pháp khác để giải quyết bài toán này, như sử dụng thuật toán hoặc mã nguồn tính toán.

Cài đặt bài toán 8 hậu với Python

Dưới đây là một cài đặt đơn giản của bài toán 8 quân Hậu trên bàn cờ vua bằng ngôn ngữ Python, sử dụng thuật toán quay lui (backtracking) để tìm tất cả các cách sắp xếp đúng 8 quân Hậu sao cho không có quân nào có thể ăn được quân nào.

def is_safe(board, row, col, n):
    """
    Hàm kiểm tra xem có thể đặt quân Hậu vào vị trí (row, col) trên bàn cờ vua hay không
    Args:
        - board (list): Bàn cờ vua (ma trận 2 chiều)
        - row (int): Dòng của vị trí cần kiểm tra
        - col (int): Cột của vị trí cần kiểm tra
        - n (int): Kích thước của bàn cờ vua (n x n)

    Returns:
        - bool: True nếu có thể đặt quân Hậu vào vị trí (row, col), False nếu không
    """
    # Kiểm tra cột trên dòng hiện tại
    for i in range(row):
        if board[i][col] == 1:
            return False

    # Kiểm tra đường chéo chính (trên bên trái)
    i, j = row, col
    while i >= 0 and j >= 0:
        if board[i][j] == 1:
            return False
        i -= 1
        j -= 1

    # Kiểm tra đường chéo phụ (trên bên phải)
    i, j = row, col
    while i >= 0 and j < n:
        if board[i][j] == 1:
            return False
        i -= 1
        j += 1

    return True

def solve_n_queens(board, row, n, result):
    """
    Hàm giải bài toán 8 quân Hậu bằng thuật toán quay lui
    Args:
        - board (list): Bàn cờ vua (ma trận 2 chiều)
        - row (int): Dòng hiện tại cần đặt quân Hậu
        - n (int): Kích thước của bàn cờ vua (n x n)
        - result (list): Danh sách chứa tất cả các cách sắp xếp đúng 8 quân Hậu

    Returns:
        None
    """
    if row == n:
        # Nếu đã đặt được 8 quân Hậu, thêm bàn cờ vua vào kết quả
        result.append([row[:] for row in board])
        return

    for col in range(n):
        if is_safe(board, row, col, n):
            board[row][col] = 1
            solve_n_queens(board, row + 1, n, result)
            board[row][col] = 0

def solve_n_queens_wrapper(n):
    """
    Hàm gọi giải bài toán 8 quân Hậu
    Args:
        - n (int): Kích thước của bàn cờ vua (n x n)

    Returns:
        - list: Danh sách chứa tất cả các cách sắp xế
        - đúng 8 quân Hậu trên bàn cờ vua
    """
    board = [[0 for _ in range(n)] for _ in range(n)]
    result = []
    solve_n_queens(board, 0, n, result)
    return result

# Test với bàn cờ vua 8x8
n = 8
solutions = solve_n_queens_wrapper(n)

# In tất cả các cách sắp xếp đúng 8 quân Hậu trên bàn cờ vua
print(f"Tổng cộng có {len(solutions)} cách sắp xếp đúng 8 quân Hậu trên bàn cờ vua {n}x{n}:")
for idx, solution in enumerate(solutions):
    print(f"Cách {idx + 1}:")
    for row in solution:
        print(row)
    print("\n")

Kết quả sẽ là tất cả các cách sắp xếp đúng 8 quân Hậu trên bàn cờ vua 8×8. Tùy vào máy tính và thời gian chạy, số lượng cách sắp xếp này có thể khác nhau, vì bài toán 8 quân Hậu là một bài toán đòi hỏi tính toán khá phức tạp. Nếu bạn muốn giải bài toán với kích thước lớn hơn, bạn có thể thay đổi giá trị của biến n và chạy lại mã nguồn để tìm ra tất cả các cách sắp xếp đúng 8 quân Hậu trên bàn cờ vua lớn hơn. Tuy nhiên, với kích thước lớn, thời gian chạy có thể tăng đáng kể và cần phải được đối chiếu với hiệu năng của máy tính.

Cài đặt bài toán 8 hậu với C++

#include <iostream>
#include <vector>

using namespace std;

void solveNQueens(vector<vector<int>>& board, int row, int n, vector<vector<vector<int>>>& solutions) {
    if (row == n) {
        solutions.push_back(board);
        return;
    }

    for (int col = 0; col < n; col++) {
        if (board[row][col] == 0) {
            board[row][col] = 1;

            for (int i = row + 1; i < n; i++) {
                board[i][col] = -1; // Đánh dấu các ô cùng cột với quân hậu đã đặt
                if (col - (i - row) >= 0) {
                    board[i][col - (i - row)] = -1; // Đánh dấu các ô trên đường chéo trái trên
                }
                if (col + (i - row) < n) {
                    board[i][col + (i - row)] = -1; // Đánh dấu các ô trên đường chéo phải trên
                }
            }

            solveNQueens(board, row + 1, n, solutions); // Đệ quy để đặt các quân hậu tiếp theo

            for (int i = row + 1; i < n; i++) {
                board[i][col] = 0; // Xóa đánh dấu các ô cùng cột với quân hậu đã đặt
                if (col - (i - row) >= 0) {
                    board[i][col - (i - row)] = 0; // Xóa đánh dấu các ô trên đường chéo trái trên
                }
                if (col + (i - row) < n) {
                    board[i][col + (i - row)] = 0; // Xóa đánh dấu các ô trên đường chéo phải trên
                }
            }

            board[row][col] = 0; // Quay lại trạng thái trước đó
        }
    }
}

vector<vector<vector<int>>> solveNQueens(int n) {
    vector<vector<int>> board(n, vector<int>(n, 0));
    vector<vector<vector<int>>> solutions;
    solveNQueens(board, 0, n, solutions);
    return solutions;
}

int main() {
    int n = 8;
    vector<vector<vector<int>>> solutions = solveNQueens(n);

    cout << "Tong cong co " << solutions.size() << " cach sap xep dung 8 quan Hau tren ban co vua " << n << "x" << n << ":\n";
    for (int idx = 0; idx < solutions.size(); idx++) {
        cout << "Cach " << idx + 1 << ":\n";
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (solutions[idx][i][j] == 1) {
                    cout << "H ";
                } else {
                    cout << ". ";
                }
            }
            cout << endl;
        }
        cout << endl;
    }

    return 0;
}

Trên đây, chúng ta đã sử dụng phương pháp đệ quy để giải quyết bài toán 8 quân Hậu, với mỗi lần đặt quân Hậu vào bàn cờ, chúng ta đánh dấu các ô cùng hàng, cột và đường chéo với quân Hậu đã đặt, sau đó tiếp tục đệ quy để đặt quân Hậu tiếp theo. Nếu sau khi đặt quân Hậu xong mà không tìm được cách đặt nào hợp lệ, chúng ta sẽ quay lại trạng thái trước đó và thử cách đặt khác. Sau khi hoàn thành tất cả các cách đặt quân Hậu, chúng ta sẽ in ra màn hình các bàn cờ đã được giải quyết. Trong đó, ‘H’ đại diện cho quân Hậu và ‘.’ đại diện cho ô trống trên bàn cờ. Có thể có nhiều cách giải khác nhau và số lượng cách giải phụ thuộc vào kích thước của bàn cờ và vị trí ban đầu của quân Hậu. Nếu kích thước bàn cờ lớn hơn, thì số lượng cách giải sẽ càng nhiều. Chúc bạn thành công!

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *