首页 > 其他分享 >回溯法--N皇后问题

回溯法--N皇后问题

时间:2023-05-29 21:02:21浏览次数:25  
标签:-- int board 放置 回溯 皇后 col row

@TOC

一、问题描述

1、按照国际象棋的规则,皇后可以进攻与之处在同一行或同一列或同一斜线上的棋子。 2、n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互进攻。

二、示例

2.1 四皇后的2个可行解

回溯法--N皇后问题_System

2.2 过程图示

以四皇后为例,展示寻找一种可行解的过程

回溯法--N皇后问题_递归_02

三、问题分析

3.1涉及到的概念

递归

自己调自己,在方法中调用方法本身。 使用递归需要注意: 1、递归要有出口,不能是死循环,死循环会造成栈溢出。 2、递归次数不宜过多,过多也会有栈溢出的问题。

回溯

回溯法是一种解决问题的算法,它会尝试每一种可能的解决方案来找到最佳解。

3.2 分析

回溯法一般通过递归实现。在n皇后问题中,我们可以从第一行开始,每行放置皇后,检查该皇后是否与之前的皇后冲突,如果没有则放置下一行的皇后,如果发现无解则回溯到上一行重新尝试。

回溯用递归的方式去控制for嵌套的层数,4×4递归4层,每一层有一个for循环,遍历每一层对应的位置。时间复杂度和嵌套for循环一致。

四、 代码实现

4.1 实现思路

宏观:

使用深度搜索的方法,按照先行后列的顺序,查看每一个位置是否满足条件。

微观:

  1. 定义二维数组表示棋盘,定义一个变量n表示几个皇后
  2. 定义一个方法用来判断当前摆放的皇后是否与之前的皇后冲突(同列、左上方,右上方),冲突返回0;否则,返回1,表示此位置可以放置皇后。
  3. 定义一个递归函数,尝试在当前行放置皇后。

这里给一个回溯代码模板

if(终止条件){
    收集结果;
    return;
}

for(遍历本层集合中的元素){
    处理节点;
    递归;
    回溯,撤销处理结果
}

4.2 递归函数NS图

回溯法--N皇后问题_System_03

4.3 代码

package com.lsn.NQueen;

public class NQueens {

    // 定义一个二维数组表示棋盘
    int[][] board;

    // 定义一个变量表示几个皇后
    int n;

    // 构造函数,初始化棋盘和n
    public NQueens(int n) {
        board = new int[n][n];
        this.n = n;
    }

    // 判断当前摆放的皇后是否与之前的皇后冲突
    public boolean isSafe(int row, int col) {
        int i, j;

        // 检查当前列是否有皇后
        for (i = 0; i < row; i++) {
            if (board[i][col] == 1) {
                return false;
            }
        }

        // 检查左上方是否有皇后
        for (i = row, j = col; i >= 0 && j >= 0; i--, j--) {
            if (board[i][j] == 1) {
                return false;
            }
        }

        // 检查右上方是否有皇后
        for (i = row, j = col; i >= 0 && j < n; i--, j++) {
            if (board[i][j] == 1) {
                return false;
            }
        }

        // 如果都没有冲突,则返回true
        return true;
    }

    // 递归函数,尝试在当前行放置皇后
    public boolean solve(int row) {
        // 如果所有行都已经摆放完毕,则返回true(终止条件,收集结果)
        if (row == n) {
            return true;
        }

        // 尝试在当前行的每一列放置皇后(单层逻辑,处理节点)
        for (int col = 0; col < n; col++) {
            // 判断当前位置是否安全
            if (isSafe(row, col)) {
                // 如果安全,则将皇后放置在当前位置
                board[row][col] = 1;

                // 递归调用solve函数,尝试在下一行放置皇后
                if (solve(row + 1)) {
                    return true;
                }

                // 如果下一行无法放置皇后,则回溯到当前行,重新尝试放置皇后(撤销处理节点的情况)
                board[row][col] = 0;
            }
        }

        // 如果当前行的每一列都无法放置皇后,则返回false
        return false;
    }

    // 打印棋盘
    public void printBoard() {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print(board[i][j] + " ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        // 创建一个NQueens对象,并初始化规模为8
        NQueens nQueens = new NQueens(3);

        // 调用solve函数,尝试解决N皇后问题
        if (nQueens.solve(0)) {
            // 如果找到了解,则打印棋盘
            nQueens.printBoard();
        } else {
            // 如果没有找到解,则打印无解
            System.out.println("No solution found.");
        }
    }
}

标签:--,int,board,放置,回溯,皇后,col,row
From: https://blog.51cto.com/u_15843729/6373827

相关文章

  • 【数据结构】图
    图的定义和基本术语边或弧可以关联相应的值,这些值称作边或弧的权,带权图通常称作网。对于无向图G=(V,{E}),如果边(v,v’)∈E,则称v和v’互为邻接点,或称v和v’相邻接。此时称边(v,v’)依附于顶点v和v’,或边(v,v’)和顶点v和v’相关联。和顶点v相关联的边的数目称为顶点v的度,......
  • 数电票是否打印,看这一篇就够了~
     近日,财政部会计司发布了《关于公布电子凭证会计数据标准(试行版)的通知》,为做好电子凭证会计数据标准深化试点工作,研究制定了9类电子凭证的会计数据标准。在通知的《电子凭证会计数据标准——全面数字化的电子发票(试行版)》指南中,明确了数电票报销入账归档的具体处理方式。    ......
  • 【Java】你真的了解抽象类和接口?
    一、抽象类在Java中,一个类如果被abstract修饰称为抽象类,抽象类中被abstract修饰的方法称为抽象方法**,抽象方法不用给出具体的实现体**。publicclassTestDemo{publicstaticvoidmain(String[]args){Circlec=newCircle();c.setR(5);c.......
  • 回访补量打通客户流失点,增强品牌市场竞争力
       回访补量是一种常用的品牌营销策略,可以有效打通客户流失点,增强品牌的市场竞争力。以下是一些企业可以采用的方法,帮助他们通过回访补量策略提升品牌的竞争力。持续关注客户需求:企业应该通过回访、问卷、客户反馈等方式,了解客户的需求、反馈和建议,在此基础上,定制精准的服务......
  • 斐波那契数列:2.数组
    斐波那契数列:2.数组#include<stdio.h>intfib(intm){inti;inta[100]={0,1,1};for(i=2;i<=m;i++){a[i]=a[i-1]+a[i-2];}returna[m];}intmain(){intn;scanf("%d",&n);printf("%d",fib(n));return0......
  • Typroa主题替换
    Typroa主题替换从这里下载主题1.解压后:2.拷贝到typroa的主题目录下(打开typroa->偏好设置->外观->打开主题文件夹)3.拷贝后:4.重新打开typroa,选择Ctf主题即可。......
  • Codeforces Round 875 (Div
    CodeforcesRound875(Div.2)C-D题解CProblem-C-Codeforces我们发现题述所形成的父亲节点一定比子节点先画出,并且如果子节点顺序在父节点后面,则父,子节点为同一个周期加入。反之,则子节点的周期为父节点+1。所以做法考虑树上dp,维护第i个节点加入树的周期。转移方程如下:\[......
  • 基于QT的空闲教室预约系统[2023-05-29]
    基于QT的空闲教室预约系统[2023-05-29][课程设计选题十]空闲教室预约系统课程设计内容利用QtCreater等工具和Linux环境下时间日期API实现一个基于图形界面的空闲教室预约系统,自行构建界面,可以实现选择日期、教学楼、教室座位数,查询相应空闲教室情况,录用申请信息,教室管理员......
  • 如何使用 Megatron-LM 训练语言模型
    在PyTorch中训练大语言模型不仅仅是写一个训练循环这么简单。我们通常需要将模型分布在多个设备上,并使用许多优化技术以实现稳定高效的训练。HuggingFace......
  • IO系统
    IO系统这一章主要讲的就是IO的四种控制方式,首先对这四种方式进行一个简单介绍,下面再对着四种方式分别进行介绍。程序查询方式:由cpu通过程序不断查询IO设备是否已经做好准备,从而控制IO设备于主机进行信息交换程序中断方式:只在IO设备准备就绪并想cpu发出中断请求时才予以响应DMA......