【回溯算法】n-皇后

导航

    • 题目来源
    • 题目描述
    • 示例
    • 思路
    • 完整代码

题目来源

n-皇后

题目描述

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的n 皇后问题的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中'Q' 和 '.'分别代表了皇后和空位。

示例

在这里插入图片描述

思路

这道题是根据labuladong算法秘籍刷到的

回溯的过程可以看作是决策树中做决策与撤回决策,决策就是走向下一层,撤回决策就是返回。
在这里插入图片描述

核心代码:

void backtrack(当前选择, 剩余选择列表) {
	if (当前选择产生的结果满足结束递归条件) {
		return;
	}
	
	for (选择 in 剩余选择列表) {
		//做出当前选择
		st[选择] = true;
		// 进入下一层决策树
		backtrack(选择 ,剩余选择列表);
		// 撤回选择
		st[选择] = false;
	}
}
  • 在本题中决策树的每一层表示棋盘上的每一行;每个节点可以做出的选择是,在该行的任意一列放置一个皇后。
  • 回溯的过程中,当前考虑行的前面所有行已经做过选择

回溯函数

/**
    @description: 回溯函数,如果当前递归到row行,前row-1行已经放置好皇后
    @param: borad - 棋盘
    @param: row - 当前到第几行了
    */
    void backtrack(vector<string> &borad, int row) {
        if (row == borad.size()) {
            res.push_back(borad);
            return;
        }

        int n = borad[row].size();

        for (decltype(borad.size()) i = 0; i < n; ++ i) {
            // 判断row 行 i 列可不可以放皇后
            if (!valid(borad, row, i)) {
                // 不能放
                continue;
            }

            // 放置皇后
            borad[row][i] = 'Q';
            // 继续下一行棋盘
            backtrack(borad, row + 1);
            // 不放
            borad[row][i] = '.';
        }
    }

valid函数用于判断当前位置是否可以放置皇后:
如果当前位置所在行、列、正对角线、负对角线有放置皇后,那么当前位置就不可以放置皇后了

valid函数

/**
        @param: board  棋盘
        @param: row  行
        @param: line 列
        @return bool类型,true表示可以放,false表示不可以放
    */
    bool valid(vector<string> &board, int row, int line) {
        int n = board.size();
        // 同一行是否放了皇后
        for (int j = 0; j < line; ++ j) {
            if (board[row][j] == 'Q') return false;
        }

        // 同一列是否放了皇后
        for (int i = 0; i < row; ++ i) {
            if (board[i][line] == 'Q') return false;
        }

        // 左斜线是否放了皇后
        int b = line - row;
        for (int i = 0; i < row; ++i) {
            int j = i + b;
            if (j < 0) continue;
            if (board[i][j] == 'Q') return false;
        }

        // 右斜线是否放了皇后
        b = row + line;
        for (int i = 0; i < row; ++ i) {
            int j = b - i;
            if (j < 0) continue;
            if (board[i][j] == 'Q') return false;
        }
        // 都没有放皇后
        return true;
    }

这里解释一下为什么正对角、负对角这么计算:将棋盘想象成下面样子
在这里插入图片描述

正对角的情况如下:
在这里插入图片描述
对于当前位置(row, line),我们可以确定这条对角线:计算b = y - x;
所以b = line - row, 然后从 0 ~ row - 1 计算每一个 y值, 然后要保证y值为正

负对角同理

完整代码

class Solution {
public:
    vector<vector<string>> res;
    vector<vector<string>> solveNQueens(int n) {
        vector<string> borad(n, string(n, '.'));

        // 回溯
        backtrack(borad, 0);
        return res;
    }

    /**
    @description: 回溯函数,如果当前递归到row行,前row-1行已经放置好皇后
    @param: borad - 棋盘
    @param: row - 当前到第几行了
    */
    void backtrack(vector<string> &borad, int row) {
        if (row == borad.size()) {
            res.push_back(borad);
            return;
        }

        int n = borad[row].size();

        for (decltype(borad.size()) i = 0; i < n; ++ i) {
            // 判断row 行 i 列可不可以放皇后
            if (!valid(borad, row, i)) {
                // 不能放
                continue;
            }

            // 放置皇后
            borad[row][i] = 'Q';
            // 继续下一行棋盘
            backtrack(borad, row + 1);
            // 不放
            borad[row][i] = '.';
        }
    }

    /**
        @param: board  棋盘
        @param: row  行
        @param: line 列
        @return bool类型,true表示可以放,false表示不可以放
    */
    bool valid(vector<string> &board, int row, int line) {
        int n = board.size();
        // 同一行是否放了皇后
        for (int j = 0; j < line; ++ j) {
            if (board[row][j] == 'Q') return false;
        }

        // 同一列是否放了皇后
        for (int i = 0; i < row; ++ i) {
            if (board[i][line] == 'Q') return false;
        }

        // 左斜线是否放了皇后
        int b = line - row;
        for (int i = 0; i < row; ++i) {
            int j = i + b;
            if (j < 0) continue;
            if (board[i][j] == 'Q') return false;
        }

        // 右斜线是否放了皇后
        b = row + line;
        for (int i = 0; i < row; ++ i) {
            int j = b - i;
            if (j < 0) continue;
            if (board[i][j] == 'Q') return false;
        }
        // 都没有放皇后
        return true;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

thinkphp学习02-目录结构、控制器、路由、配置文件

目录结构 www WEB部署目录&#xff08;或者子目录&#xff09; ├─app 应用目录 │ ├─controller 控制器目录 │ ├─model 模型目录 │ ├─ ... 更多类库目录 │ │ │ ├─common.php 公共函数文件 │ └─event.ph…

STM32MP157D-DK1 STM32CubeID使用与M核开发

STM32MP157具有A7内核核M4内核&#xff0c;前面介绍的一些文章&#xff0c;都是在A7内核上进行的&#xff0c;本篇来介绍M4内核的开发&#xff0c;以及开发时要用到的STM32 CubeIDE软件的使用。 1 STM32 CubeIDE创建LED工程 STM32CubeIDE是一体式多操作系统开发工具&#xff…

Python 全栈体系【四阶】(十一)

第四章 机器学习 机器学习&#xff1a; 传统的机器学习&#xff1a;以算法为核心深度学习&#xff1a;以数据和计算为核心 感知机 perceptron&#xff08;人工神经元&#xff09; 可以做简单的分类任务掀起了第一波 AI 浪潮 感知机不能解决线性不可分问题&#xff0c;浪潮…

Vue3.x+Echarts (可视化界面)

Vue3.0Echarts &#xff08;可视化界面&#xff09; 1. 简介1.1 技术选型1.2 ECharts支持的数据格式1.3 ECharts使用步骤 2. ECharts图形2.1 通用配置2.2 柱状图2.3 折线图2.4 散点图2.5 直角坐标系常用配置2.6 饼图2.7 地图2.8 雷达图2.9 仪表盘2.10 小结 3. Vue3.2ECharts5数…

腾讯云com域名注册1元条件说明

腾讯云com域名注册优惠价格1元首年&#xff0c;条件是企业新用户&#xff0c;个人新用户注册com域名是33元首年&#xff0c;第二年续费价格85元一年。活动 txybk.com/go/domain-sales 活动打开如下图&#xff1a; 腾讯云com域名注册优惠价格 腾讯云com域名注册原价是85元一年&a…

计算机毕业设计----SSM场地预订管理系统

项目介绍 本项目分为前后台&#xff0c;前台为普通用户登录&#xff0c;后台为管理员登录&#xff1b; 用户角色包含以下功能&#xff1a; 按分类查看场地,用户登录,查看网站公告,按分类查看器材,查看商品详情,加入购物车,提交订单,查看订单,修改个人信息等功能。 管理员角…

杨中科 ASP.NETCore WebAPI 控制器及返回值、参数问题

控制器及返回值 控制器类 1、ControllerBase与Controller webapi的controller 继承自 ControllerBase webmvc 继承自controller controller 继承自controllerbase 2、控制器类可以不显式地继承自任何类 还是需要添加特性 运行&#xff1a; Action方法的异步 1、Acti…

Windows11下载安装nacos(2.3.0)详解

一、环境要求 windows7以上 jdk8及以上版本&#xff0c;并且配置了JAVA_HOME环境变量 二、nacos下载解压 release版本地址:Releases alibaba/nacos GitHub 下载后解压即可&#xff0c;上面的tar.gz是linux版本 解压后如下 nacos自己内置有数据库derby&#xff0c;我用的是…

国产编程语言炫彩,界面库ui dll,有人了解吗

中文编程: 中英文双语编程, 中英一键切换, 中英对照, 中文为主, UNICODE/ANSI编码都支持; 完全免费: 炫语言免费, 调试器免费, IDE绿色版无需安装; 纯文本: 纯文本格式代码, 随意复制粘贴, GIT代码托管, 多人合作开发; PY风格: PY风格代码, 通过代码缩进确定作用域 非 大花括…

腾讯面试总结

腾讯 一面 mysql索引结构&#xff1f;redis持久化策略&#xff1f;zookeeper节点类型说一下&#xff1b;zookeeper选举机制&#xff1f;zookeeper主节点故障&#xff0c;如何重新选举&#xff1f;syn机制&#xff1f;线程池的核心参数&#xff1b;threadlocal的实现&#xff…

RFID传感器|识读器CNS-RFID-01/1S在AGV小车|搬运机器人领域的安装与配置方法

AGV 在运行时候需要根据预设地标点来执行指令&#xff0c;在需要 AGV 在路径线上位置执行某个指令时候&#xff0c;则需要在这个点设置 命令地标点&#xff0c;AGV 通过读取不同地标点编号信息&#xff0c;来执行规定的指令。读取地标点设备为寻址传感器&#xff0c;目前&#…

【MIT 6.S081】2020, 实验记录(1),Lab: Xv6 and Unix utilities

目录 实验准备TasksTask 1: Boot xv6Task 2: sleepTask 3: pingpongTask 4: primesTask 5: findTask 6: xargs 实验准备 这个 lab 用来学习尝试如何通过 system call 来实现常见的 shell 命令行程序&#xff0c;比如 ls、sleep、xargs 等。 实验官网 可以使用 docker 搭建实…

JetPack组件学习ViewModel

ViewModel的使用 1.需要先创建ViewModel类&#xff0c;继承自ViewModel重写onclear方法&#xff0c;使得页面销毁的时候能够走到自定义的onClear方法中 class MyViewModel : ViewModel() {//共享数据的核心在于拿到同一个LiveData实例&#xff0c;也就是拿到同一个ViewModel实…

Windows10升级到Windows11 Office未激活解决方案

Windows11出了很久了&#xff0c;昨天才升级&#xff0c;今天打开Word发现激活不了&#xff0c;我的是2019的版本&#xff0c;然后发现是Windows系统的注册表的问题&#xff0c;想要找到解决方案还不简单&#xff0c;所以记录一下。 解决方案&#xff1a; Win r打开输入rege…

进程间通信之匿名管道和命名管道的理解和实现【Linux】

进程间通信之匿名管道和命名管道的理解和实现 进程间通信什么是管道匿名管道代码实现管道的读写规则管道特点 命名管道创建命名管道代码实现 进程间通信 进程间通信的目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#xff1a;多个进程之间共享同…

Unity 利用UGUI之Slider制作进度条

在Unity中使用Slider和Text组件可以制作简单的进度条。 首先在场景中右键->UI->Slider&#xff0c;新建一个Slider组件&#xff1a; 同样方法新建一个Text组件&#xff0c;最终如图&#xff1a; 创建一个进度模拟脚本&#xff0c;Slider_Progressbar.cs using System.C…

php实现支付宝商户转账

目录 一&#xff1a;背景介绍 一&#xff1a;准备工作 三&#xff1a;代码实现 一&#xff1a;背景介绍 最近工作中&#xff0c;要用到支付宝的商家转账功能&#xff0c;用php代码实现&#xff0c;网上找的内容&#xff0c;有些是老版本的实现&#xff0c;有些是调用sdk&am…

代码随想录二刷 |二叉树 | 验证二叉搜索树

代码随想录二刷 &#xff5c;二叉树 &#xff5c; 验证二叉搜索树 题目描述解题思路递归法迭代法 代码实现递归法迭代法 题目描述 98.验证二叉搜索树 给定一个二叉树&#xff0c;判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有如下特征&#xff1a; 节点的左子…

解决:Unity : Error while downloading Asset Bundle: Couldn‘t move cache data 问题

目录 问题&#xff1a; 尝试 问题得到解决 我的解释 问题&#xff1a; 最近游戏要上线&#xff0c;发现一个现象&#xff0c;部分机型在启动的时候闪退或者黑屏&#xff0c;概率是5%左右&#xff0c;通过Bugly只有个别机型才有这个现象&#xff0c;其实真实情况比这严重的多…

Async In C#5.0(async/await)学习笔记

此文为Async in C#5.0学习笔记 1、在async/await之前的异步 方式一&#xff1a;基于事件的异步Event-based Asynchronous Pattern (EAP). private void DumpWebPage(Uri uri) {WebClient webClient new WebClient();webClient.DownloadStringCompleted OnDownloadStringCo…