经典回溯算法解析

八皇后问题

要求在8×8的国际象棋棋盘上放置8个皇后,使得它们互不攻击(即任意两个皇后不在同一行、同一列或同一对角线上)。

python 复制代码
# 统计所有合法摆放方式的数量
def eight_queens():
    count = 0  # 统计合法解的数量
    # 初始化占用标记数组(索引1-8有效,0弃用)
    row_use = [False] * 9  # 行占用(实际按行递归,这个数组其实用不上,可删)
    col_use = [False] * 9  # 列占用
    zhu_use = [False] * 17  # 主对角线
    fu_use = [False] * 17  # 副对角线

    # 回溯函数:处理第row行的皇后放置(必须嵌套在eight_queens内,否则访问不到外部变量)
    def back(row):
        nonlocal count
        # 终止条件:8行全部放置完成,找到一个合法解
        if row > 8:
            count += 1
            return

        # 遍历当前行的所有列(1-8,col=扣)
        for col in range(1, 9):
            # 核心判断:列、主对角线、副对角线都未被占用
            if not col_use[col] and not zhu_use[row + col] and not fu_use[row - col + 8]:
                # 标记占用(放置皇后)
                col_use[col] = True
                zhu_use[row + col] = True
                fu_use[row - col + 8] = True

                # 递归处理下一行
                back(row + 1)

                # 回溯:取消标记(移除皇后)
                col_use[col] = False
                zhu_use[row + col] = False
                fu_use[row - col + 8] = False

    # 从第1行开始回溯(调用回溯函数,缩进必须在eight_queens内)
    back(1)
    # 返回最终统计结果
    return count


# 定义main函数,调用eight_queens并输出结果
def main():
    result = eight_queens()
    print(result)  # 输出:92


# 执行入口
if __name__ == "__main__":
    main()

数独填数问题

37. 解数独 - 力扣(LeetCode)

数独是一种逻辑游戏,需要在9x9的格子中填入数字1-9,满足以下条件:

  • 每一行必须包含数字1-9且不重复。
  • 每一列必须包含数字1-9且不重复。
  • 每个3x3的小宫格(共9个)必须包含数字1-9且不重复。
python 复制代码
# 检查(x,y)位置填入num是否合法
def is_valid(board, x, y, num):
    # 检查行
    for i in range(9):
        if board[x][i] == num:
            return False
    # 检查列
    for i in range(9):
        if board[i][y] == num:
            return False
    # 检查3×3宫
    sx = x // 3 * 3
    sy = y // 3 * 3
    for i in range(3):
        for j in range(3):
            if board[sx+i][sy+j] == num:
                return False
    return True

# DFS回溯求解数独
def dfs(board):
    for i in range(9):
        for j in range(9):
            if board[i][j] == 0:
                for num in range(1, 10):
                    if is_valid(board, i, j, num):
                        board[i][j] = num
                        if dfs(board):
                            return True
                        board[i][j] = 0  # 回溯
                return False
    return True

# 主程序
if __name__ == "__main__":
    board = []
    # 读取9行空格分隔的数独输入(0表示空白)
    for _ in range(9):
        line = input().strip()
        row = list(map(int, line.split()))
        board.append(row)
    # 求解并按标准格式输出
    if dfs(board):
        for row in board:
            print(' '.join(map(str, row)))
    else:
        print("无解")
核心点 数独 / 皇后问题通用逻辑
回溯核心 「试填→验证→递归→回溯」:试选一个值→验证合法性→递归填下一个→错了就回退(恢复现场)
终止条件 所有位置填完(数独无 0 / 皇后放满 N 个)→返回 True;某位置无合法值→返回 False 触发回溯
核心价值 暴力枚举的优化:提前剪枝(非法值不递归),避免无效计算,适配蓝桥杯中等难度算法题
相关推荐
Ln5x9qZC24 分钟前
尾递归与Continuation
算法
一路向北he4 分钟前
esp32库依赖
c语言·c++·算法
老四啊laosi5 分钟前
[双指针] 6. 查找总价为目标值的两个商品
算法·力扣·总价为目标值得两商品
做cv的小昊13 分钟前
【conda】打包已有conda环境并在其他服务器上搭建
运维·服务器·python·conda·运维开发·pip·开发
Hommy8816 分钟前
【开源剪映小助手-客户端】目录扫描功能
python·开源·aigc·剪映小助手
Pocker_Spades_A17 分钟前
Python快速入门专业版(五十六)——爬虫会话管理:Cookie与Session原理及实战(保持登录状态)
开发语言·爬虫·python
MwEUwQ3Gx17 分钟前
深入理解 Java Deque 的设计哲学
java·开发语言·python
MoRanzhi120320 分钟前
scikit-learn 决策树分类详解:从原理、可视化到剪枝实战掌握 DecisionTreeClassifier
python·决策树·机器学习·数学建模·分类·scikit-learn·剪枝
人间寥寥情难诉21 分钟前
LRU算法本地实现
java·算法·spring
moonsea020323 分钟前
2026.4.2
开发语言·c++·算法