🎯 Mục tiêu bài học

  • Hiểu cách kiểm tra ràng buộc khi đặt hậu (Q) lên bàn cờ n×n.
  • Biết cắt tỉa nhánh sai thay vì thử tất cả mọi cách mù quáng.

📘 Bài toán N-Queens là gì?

Ta cần đặt n quân Hậu sao cho:

  • Không có 2 hậu nào cùng hàng.
  • Không có 2 hậu nào cùng cột.
  • Không có 2 hậu nào cùng chéo.

Mỗi lời giải là một cách sắp xếp hợp lệ toàn bộ bàn cờ.


💻 Ý tưởng giải bằng quay lui

  1. Đặt hậu từng hàng một (row 0, row 1, ...).
  2. Ở mỗi hàng, thử đặt vào từng cột có thể.
  3. Nếu hợp lệ thì đi tiếp sang hàng sau, nếu không thì bỏ (backtrack).

C++

#include 
using namespace std;

int n;
vector col, diag1, diag2, pos;
int solutions = 0;

void backtrack(int row){
    if(row==n){
        solutions++;
        for(int r=0;r";
        }
        cout << "
"; return; } for(int c=0;c> n; col.assign(n,0); diag1.assign(2*n,0); diag2.assign(2*n,0); pos.assign(n,-1); backtrack(0); cerr << "Total solutions: " << solutions << "
"; }

Python

n = int(input())

col   = [False]*n
diag1 = [False]*(2*n)
diag2 = [False]*(2*n)
pos   = [-1]*n
solutions = 0

def backtrack(row):
    global solutions
    if row == n:
        solutions += 1
        for r in range(n):
            line = "".join("Q" if pos[r]==c else "." for c in range(n))
            print(line)
        print()
        return
    for c in range(n):
        if not col[c] and not diag1[row+c] and not diag2[row-c+n-1]:
            col[c] = diag1[row+c] = diag2[row-c+n-1] = True
            pos[row] = c
            backtrack(row+1)
            col[c] = diag1[row+c] = diag2[row-c+n-1] = False

backtrack(0)
print("Total solutions:", solutions)

🧩 Bài tập luyện tập

  1. In ra tổng số lời giải của N-Queens với n cho trước.
  2. Chỉ in ra 1 lời giải hợp lệ đầu tiên (dừng sớm).
  3. Biểu diễn lời giải không phải bằng bảng Q/. mà bằng mảng vị trí cột, ví dụ: [1, 3, 0, 2].
💡 Gợi ý lời giải dừng sớm
# Trong backtrack(row):
#   nếu đã tìm thấy lời giải đầu tiên thì return True để dừng luôn
#   nếu không thì tiếp tục thử.
# Đây là tối ưu hóa thời gian khi chỉ cần 1 lời giải.