洛谷:P1219 [USACO1.5] 八皇后 Checker Challenge Java题解

题解:八皇后

源题目地址:https://www.luogu.com.cn/problem/P1219

题目分析

题目要求我们在n×n的棋盘上放置n个皇后,使得它们互不攻击(不在同一行、同一列或同一对角线上)。需要找出所有可能的解,并按字典序输出前三个解以及解的总数。

解题思路

  1. 回溯算法:使用深度优先搜索(DFS)来尝试所有可能的皇后位置。
  2. 剪枝优化:在放置每个皇后时,检查是否与已放置的皇后冲突,避免无效搜索。
  3. 结果记录:当找到一个有效解时,记录结果并统计总数。

代码实现

import java.util.Scanner;

public class Main {
    static int n; // 棋盘大小
    static int count = 0; // 解的总数
    static boolean[] colUsed; // 标记列是否被占用
    static int[] solution; // 存储当前解

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        colUsed = new boolean[n + 1]; // 列索引从1到n
        solution = new int[n + 1]; // 存储每行皇后所在的列
        
        solve(1); // 从第1行开始放置皇后
        System.out.println(count); // 输出解的总数
    }

    // 递归函数,放置第row行的皇后
    static void solve(int row) {
        if (row > n) { // 找到一个解
            count++;
            if (count <= 3) { // 输出前三个解
                for (int i = 1; i <= n; i++) {
                    System.out.print(solution[i] + " ");
                }
                System.out.println();
            }
            return;
        }
        
        for (int col = 1; col <= n; col++) {
            if (!colUsed[col] && isSafe(row, col)) { // 检查列和对角线
                colUsed[col] = true;
                solution[row] = col;
                solve(row + 1); // 递归放置下一行
                colUsed[col] = false; // 回溯
            }
        }
    }

    // 检查(row,col)位置是否安全(不与已放置的皇后对角冲突)
    static boolean isSafe(int row, int col) {
        for (int i = 1; i < row; i++) {
            if (Math.abs(i - row) == Math.abs(solution[i] - col)) {
                return false;
            }
        }
        return true;
    }
}

复杂度分析

时间复杂度:O(n!),最坏情况下需要尝试所有可能的排列组合。
空间复杂度:O(n),用于存储标记数组和当前解。

优化说明

  1. 列标记数组:使用布尔数组快速判断列是否被占用。
  2. 对角线检查:通过数学方法检查两个皇后是否在同一对角线上。
  3. 提前终止:当找到前三个解后,继续搜索但不输出,只统计总数。

该解法能够高效处理题目给定的数据范围(6 ≤ n ≤ 13),并正确输出所有解。

你可能感兴趣的:(java,深度优先,开发语言)