【算法-回溯法】N皇后问题

news2024/11/26 2:28:40

一、问题背景

N皇后问题是由八皇后问题引申而来的。八皇后是一个以国际象棋为背景的问题,国际象棋8*8.

怎么去放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

条件n = 1或n ≥ 4

二、算法介绍

此题解的算法使用的是:回溯法(Backtracking)

回溯法是暴力搜索法里的一种。其核心是通过逐步构建空间,并在构建过程中进行选择、判断和回退,直到找到问题的解或者确定不存在解。

回溯法采用试错的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现,现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的答案。回溯法通常用最简单的递归方法来实现,在反复重复上述的步骤后可能出现两种情况:

  • 找到一个可能存在的正确的答案
  • 在尝试了所有可能的分步方法后宣告该问题没有答案

回溯法的优点是可以穷尽所有可能的解空间,并找到所有满足条件的解。但同时,由于它遍历了所有可能的解空间,所以在解空间很大的情况下,会产生指数级的时间复杂度,因此效率可能较低。

回溯法的经典应用包括:N皇后问题、组合求和、排列组合、子集、正则表达式匹配等

三、代码示例

1、C语言版本(ACM算法题目里面经典)

#include <stdio.h>
#define N 8 // N代表棋盘的大小,这里设置为8
int board[N][N]; // 棋盘数组,用于表示每个位置是否放置皇后

// 检查当前位置(row, col)是否可以放置皇后
int isSafe(int row, int col) {
    int i, j;
    // 检查当前列是否有皇后冲突
    for (i = 0; i < row; i++) {
        if (board[i][col] == 1) {
            return 0;
        }
    }
    // 检查当前位置的左上方是否有皇后冲突
    for (i = row, j = col; i >= 0 && j >= 0; i--, j--) {
        if (board[i][j] == 1) {
            return 0;
        }
    }
    // 检查当前位置的右上方是否有皇后冲突
    for (i = row, j = col; i >= 0 && j < N; i--, j++) {
        if (board[i][j] == 1) {
            return 0;
        }
    }
    return 1; // 当前位置可以放置皇后
}

// 使用回溯法解决N皇后问题
int solveNQueens(int row) {
    if (row == N) {
        // 打印解
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                printf("%d ", board[i][j]);
            }
            printf("\n");
        }
        printf("\n");
      
        // 只打印一个解的话,可以使用 return 1; 终止程序
        // return 1;
    }

    for (int col = 0; col < N; col++) {
        if (isSafe(row, col)) {
            // 当前位置可以放置皇后
            board[row][col] = 1;
            // 递归调用解决下一行
            solveNQueens(row + 1);
            // 回溯,撤销当前位置的选择
            board[row][col] = 0;
        }
    }

    return 0; // 所有解都已找到
}

int main() {
    solveNQueens(0); // 从第一行开始解决N皇后问题
    return 0;
}

2、JS版本 (主要是思想)

function solveNQueens(n) {
  // 存储结果的数组
  let result = [];

  // 执行回溯算法
  backtrack([], [], [], result, n);

  // 返回结果数组
  return result;
}

// 回溯函数
function backtrack(board, cols, diagonals1, diagonals2, n) {
  // 当前棋盘的大小等于N时,表示已找到一种解法,将其存入结果数组
  if (board.length === n) {
    result.push(board.slice());
    return;
  }

   // 遍历当前行的每一列
  for (let col = 0; col < n; col++) {
    // 当前格子的行索引
    let row = board.length;
    
    // 根据皇后的摆放规则判断当前位置是否可行
    if (
      !cols.includes(col) &&                // 列上无冲突
      !diagonals1.includes(row - col) &&    // 主对角线无冲突
      !diagonals2.includes(row + col)       // 副对角线无冲突
    ) {
      // 将当前位置加入相应的集合中,表示皇后占据了该位置
      board.push(col);
      cols.push(col);
      diagonals1.push(row - col);
      diagonals2.push(row + col);
      
      // 继续递归搜索下一行
      backtrack(board, cols, diagonals1, diagonals2, n);
      
      // 搜索完之后,将当前位置从集合中移除,以便进行下一次搜索
      board.pop();
      cols.pop();
      diagonals1.pop();
      diagonals2.pop();
    }
  }
}

// 通过维护cols、diagonals1和diagonals2三个集合,来判断当前位置是否符合皇后的放置规则。
// 如果找到一种解法,将其存入结果数组中,并继续搜索下一行的解法。
// 在搜索完一条路径之后,需要将当前位置从集合中移除,以便进行下一次搜索。

四、结果

八皇后:12个解

四皇后:2个解

(1,3,0,2)

(2,0,3,1)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1097461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

每日汇评:黄金的回调可能会在周五上涨3%之后延续

在连续两天的积极势头下&#xff0c;金价正挑战1880美元的关键水平&#xff1b; 美元跟随美债收益率走低&#xff0c;美联储持谨慎态度&#xff0c;情绪乐观&#xff1b; 黄金价格正处于关键时刻&#xff0c;等待美国通胀数据带来新的方向性走势&#xff1b; 金价正在回撤上周五…

C# OpenCvSharp 利用Lab空间把春天的场景改为秋天

效果 项目 代码 using OpenCvSharp; using System; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms;namespace OpenCvSharp_Demo {public partial class Form1 : Form{public Form1(){InitializeComponent();}st…

安捷伦N8974A分析仪

安捷伦N8974A分析仪 N8974A 是 Agilent 的二手分析仪。分析仪是测试工程、医疗、汽车和技术行业电子设备的关键工具。使用分析仪来监控许多不同类型的电子设备的性能。您可能需要分析仪来测量音频频谱、电压和电流、信号和频率等分量 频率范围&#xff1a;10 MHz 至 6.7 GHz 一…

前端代码优化之从系统区分处理的业务场景看如何优化代码中的if判断

最近有个三端统一的技术场景&#xff0c;主要是以前移动端的 hybrid 网页在不考虑 UI 适配的情况下、期望能够直接在 PC 客户端投放。在评估修改面的时候发现了一段可以深思的代码&#xff1a; if (platform iphone) {location.href iphoneClientUrl; } else {location.href…

白皮书 |得帆云低代码aPaaS X OA全新解决方案,解锁数字化协作新境界

进入正题之前&#xff0c;我们先看两个大厂案例&#xff1a; 10年IBM Lotes OA迁移 -来自国内500强发动机全链路制造公司 主要有如下几个痛点&#xff1a; 系统老旧&#xff0c;扩展性一般&#xff0c;无法集成现有的其他业务系统 随着人员的增加&#xff0c;经常性的出现卡…

linux U盘无法使用,提示“Partition table entries are not in disk order“

问题&#xff1a; U盘在Windows上使用正常&#xff0c;在linux下无法使用fdisk -l 命令提示&#xff1a;Partition table entries are not in disk order $ fdisk -l Disk /dev/sdb: 525 MB, 525336576 bytes 17 heads, 59 sectors/track, 1022 cylinders Units cyl…

ArkTS及openHarmony

补充 padding&#xff1a;内边距&#xff0c;也就是盒子边和盒子内部的距离 margin&#xff1a;外边距&#xff0c;也就是盒子和盒子的距离 openHarmony应用开发及UI界面 常用布局 Row 水平线性布局核心代码 子控件会共享同一行&#xff0c;也就是都在同一行内 Preview C…

扩展市场版图,美格智能5G智能模组SRM955集齐全球主流认证

AIoT时代来临&#xff0c;掀起新一轮智能化终端设备的变革&#xff0c;激发应用领域的新需求。AI等新兴技术应用&#xff0c;成为拉动智能终端产品变革和市场变迁的主要力量。智能模组是AIoT时代中的核心元器件&#xff0c;是实现万物智联的关键。 美格智能作为智能模组的创领…

SpringBoot学习日记

Spring程序与SpringBoot程序对比 SpringBoot程序优点 起步依赖&#xff08;简化依赖配置&#xff09;自动装配&#xff08;简化常用工程相关配置&#xff09;辅助功能&#xff08;内置服务器&#xff0c;......&#xff09; 内嵌Tomcat REST风格 REST简介 REST&#xff0c;表…

2023年主题教育专题组织生活会对照检查材料六个方面发言材料

组织生活会发言材料&#xff0c;很多人还没写完&#xff0c;可能写着写着就不知道怎么继续了&#xff0c;其实写这类材料需要有一个好的写作框架&#xff0c;结合我们的实际情况来写。 只有那些勇敢面对困难的人&#xff0c;才能找到成功的道路。生活并非总是一帆风顺&#xff…

ant design pro v6如何引入第三方js?如腾讯地图等!

由于ant pro隐藏.html&#xff0c;需要通过他们约定的方式引入即可。 1.配置config文件 /config/config.tsheadScripts: [// 解决首次加载时白屏的问题{ src: /scripts/loading.js, async: true },{ src: "https://map.qq.com/api/gljs?v1.exp&keyOB4BZ-D4W3U-B7VV…

CountDownLatch的原理

使用CountDownLatch可以实现等待多个线程执行完毕的功能&#xff0c;实现线程之间的协调&#xff0c;让它们按照我们期望的顺序执行&#xff0c;从而避免了可能出现的并发问题。 CountDownLatch是如何实现主线程等待子线程全部结束的呢&#xff1f; 代码用例 这里我们使用一段…

【TES720D】青翼科技基于复旦微的FMQL20S400全国产化ARM核心模块

板卡概述 TES720D是一款基于上海复旦微电子FMQL20S400的全国产化核心模块。该核心模块将复旦微的FMQL20S400&#xff08;兼容FMQL10S400&#xff09;的最小系统集成在了一个50*70mm的核心板上&#xff0c;可以作为一个核心模块&#xff0c;进行功能性扩展&#xff0c;特别是用…

AN动画基础——元件,组件,散件

【AN动画基础——元件&#xff0c;组件&#xff0c;散件】 元件不同元件的作用影片剪辑按钮图形元件特性 组件组件的作用组件特性 散件散件作用散件特性 本篇内容&#xff1a;认识元件&#xff0c;组件&#xff0c;散件属性 重点内容&#xff1a;元件&#xff0c;组件&#xff…

专业翻译哪家强?插件AI来帮忙!

大多数人一提到翻译软件&#xff0c;想到的应该是某度翻译或者是某歌翻译&#xff0c;日常使用也是用这两个居多&#xff0c;但是这两个甚至市面上常见的翻译软件的效果都不是很好&#xff0c;不能精准翻译到一些专有名词的意思。 那么究竟有没有好用的AI翻译呢&#xff1f;答…

DAY06_瑞吉外卖——用户地址簿功能菜品展示购物车下单

这里写目录标题 1. 用户地址簿功能1.1 需求分析1.2 数据模型1.3 导入功能代码1.4 功能测试 2. 菜品展示2.1 需求分析2.2 前端页面分析2.3 代码开发2.3.1 查询菜品方法修改2.3.2 根据分类ID查询套餐 2.4 功能测试 3. 购物车3.1 需求分析3.2 数据模型3.3 前端页面分析3.4 准备工作…

大坑-MATLAB图片转存时需注意的点

MATLAB中图片的保存和转存有一个巨大的陷阱&#xff0c;我也是在吃了大亏后发现的&#xff0c;正常情况下&#xff0c;MATLAB跑完实验&#xff0c;生成的图片如下 放大后这样 可以方便修改坐标轴标题&#xff0c;最初我就是因为想修改坐标轴标题才给它放大的&#xff0c;因为…

Linux系统之安装ServerBee服务器监控工具

Linux系统之安装ServerBee服务器监控工具 一、ServerBee介绍1.1 ServerBee简介1.2 ServerBee特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本 四、安装ServerBee4.1 下载部署脚本4.2 解压下载文件4.3 部…

全流量安全分析发现内部系统外联异常

内部系统外连监控的重要性在于保护企业的信息安全和预防数据泄露&#xff0c;以下是几个重要的理由&#xff1a; 1、检测异常活动&#xff1a;通过监控内部系统的外连连接&#xff0c;可以及时发现是否有未经授权或异常的链接尝试。这可能表示存在恶意软件、黑客攻击或内部员工…