当前位置: 首页 > news >正文

C#八皇后算法:回溯法 vs 列优先法 vs 行优先法 vs 对角线优先法

目录

1.八皇后算法(Eight Queens Puzzle)

2.常见的八皇后算法解决方案

(1)列优先法(Column-First Method):

(2)行优先法(Row-First Method):

(3)对角线优先法(Diagonal-First Method):

(4)回溯法(Backtracking):


1.八皇后算法(Eight Queens Puzzle)

       皇后问题是一个古老而著名的问题,它实质上就是使棋盘上的8个皇后不能在同一行、同一列或同一条斜线上,共有92种方案。

2.常见的八皇后算法解决方案

        八皇后算法的解决方案有多种,以下是一些常见的解决方案:

(1)列优先法(Column-First Method):

        八皇后问题是一个经典的回溯算法问题,可以使用列优先法(或称为逐列解决法)来解决。 首先选择一个空的棋盘,然后从第一行开始,尝试将皇后放置在每一列。如果当前列没有被攻击,那么就将皇后放置在该列。否则,尝试下一列。当找到一个有效的列时,将皇后放置在该列的最下方。重复这个过程,直到所有的皇后都被放置在棋盘上。

// 使用列优先法解决八皇后问题
// 列优先算法也叫逐列解决法namespace _144_4
{class Program{private const int Size = 8;private readonly int[] queens = new int[Size];               // 存储每行皇后的列位置private readonly bool[] columns = new bool[Size];            // 列是否已被占用private readonly bool[] diagonals1 = new bool[2 * Size - 1]; // 主对角线是否已被占用private readonly bool[] diagonals2 = new bool[2 * Size - 1]; // 副对角线是否已被占用public void Solve(){PlaceQueen(0);}int solnum = 0;private void PlaceQueen(int row){if (row == Size){solnum += 1;PrintQueens(solnum);  // 所有皇后都已放置,打印结果return;}for (int col = 0; col < Size; col++){if (IsSafe(row, col)){queens[row] = col;columns[col] = true;diagonals1[row - col + Size - 1] = true;diagonals2[row + col] = true;PlaceQueen(row + 1);// 回溯diagonals2[row + col] = false;diagonals1[row - col + Size - 1] = false;columns[col] = false;}}}private bool IsSafe(int row, int col){return !columns[col] && !diagonals1[row - col + Size - 1] && !diagonals2[row + col];}private void PrintQueens(int solnum){Console.WriteLine("Solution{0}: ", solnum);for (int i = 0; i < Size; i++){for (int j = 0; j < Size; j++){if (queens[i] == j){Console.Write("Q ");}else{Console.Write("* ");}}Console.WriteLine();}Console.WriteLine();}public static void Main(string[] args){ArgumentNullException.ThrowIfNull(args);Program solver = new();solver.Solve();}}
}
  • 算法流程

        初始化所有数组。

        从第一行开始,尝试在每一列放置皇后。

        使用回溯法,如果在某一行找不到安全的位置,则返回到上一行并尝试下一个位置。

        当所有皇后都成功放置时,打印解决方案。

  • 方法分析

        Solve():启动算法,从第一行开始放置皇后。

        PlaceQueen(int row):递归方法,尝试在当前行的每一列放置皇后。如果找到一个安全的位置,则递归地尝试放置下一个皇后。如果所有皇后都已成功放置,则打印解决方案。

        IsSafe(int row, int col):检查在给定位置 (row, col) 放置皇后是否安全。如果列、主对角线和副对角线都没有被占用,则返回 true。

        PrintQueens(int solnum):打印解决方案。对于每一行,如果当前列有皇后,则打印 "Q",否则打印 "*"。

(2)行优先法(Row-First Method):

        与列优先法类似,但不同之处在于,该方法从第一列开始,尝试将皇后放置在每一行。如果当前行没有被攻击,那么就将皇后放置在该行的最右侧。否则,尝试下一行。当找到一个有效的行时,将皇后放置在该行的当前列。重复这个过程,直到所有的皇后都被放置在棋盘上。

// 使用行优先法解决八皇后问题
// 行优先算法也叫回溯法
namespace _144_3
{class Program{static void Main(string[] args){ArgumentNullException.ThrowIfNull(args);List<int[]> solutions = [];int[] solution = new int[8];Solve(0, solution, solutions);foreach (int[] sol in solutions){for (int i = 0; i < 8; i++){for (int j = 0; j < 8; j++){if (j == sol[i]){Console.Write("Q ");}else{Console.Write(". ");}}Console.WriteLine();}Console.WriteLine();}}static void Solve(int row, int[] solution, List<int[]> solutions){if (row == solution.Length){//solutions.Add(solution.ToArray()); // Add a copy of the solutionsolutions.Add([.. solution]);return;}for (int col = 0; col < solution.Length; col++){if (IsSafe(row, col, solution)){solution[row] = col;Solve(row + 1, solution, solutions);}}}static bool IsSafe(int row, int col, int[] solution){for (int i = 0; i < row; i++){if (solution[i] == col ||Math.Abs(solution[i] - col) == Math.Abs(i - row)){return false;}}return true;}}
}

        代码使用了行优先法(也称为回溯法)来解决八皇后问题,这是一个经典的递归回溯问题。 代码分析:

  • Main 方法

        Main 方法是程序的入口点。

        它首先检查 args 是否为空,如果为空则抛出异常。

        初始化一个空列表 solutions 来存储所有解决方案。

        调用 Solve 方法来寻找解决方案。

        遍历 solutions 列表,并打印出每一个解决方案。

  • Solve 方法

        Solve 方法是递归函数,用于寻找八皇后问题的解决方案。

        如果当前行 row 等于解决方案数组的长度(即8),则找到一个解决方案,并将其添加到 solutions 列表中。

        对于当前行的每一列,检查是否安全(没有冲突),如果安全则在该列放置皇后,并递归调用 Solve 方法处理下一行。

  • IsSafe 方法

        IsSafe 方法用于检查在当前位置 (row, col) 放置皇后是否安全。

        它遍历已经放置皇后的行,检查当前列和左上方对角线是否有冲突。

        如果没有冲突,返回 true;否则返回 false。

  • 注意事项

        在 Main 方法中,使用了 ArgumentNullException.ThrowIfNull(args); 来检查 args 是否为空。这通常用于命令行应用程序,但在没有实际命令行参数需求的程序中是不必要的。

        在 Solve 方法中,使用了 solutions.Add([.. solution]); 来添加解决方案的副本到 solutions 列表。这是C# 9.0引入的切片语法,用于创建数组或列表的浅拷贝。用这个简洁的方式来避免直接添加引用到同一个数组。

(3)对角线优先法(Diagonal-First Method):

        该方法首先选择一个空的棋盘,然后从左上角开始,尝试将皇后放置在对角线上。如果当前对角线没有被攻击,那么就将皇后放置在该对角线的最下方。否则,尝试下一个对角线。当找到一个有效的对角线时,将皇后放置在该对角线的当前列。重复这个过程,直到所有的皇后都被放置在棋盘上。

// 八皇后算法_对角线优先法
namespace _144_2
{class Program{static void Main(string[] args){ArgumentNullException.ThrowIfNull(args);int n = 8;int[] queens = new int[n];List<int[]> solutions = [];SolveQueens(n, queens, 0, solutions);Console.WriteLine("Total solutions: " + solutions.Count);foreach (int[] solution in solutions){for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){if (j == solution[i]){Console.Write("Q ");}else{Console.Write(". ");}}Console.WriteLine();}Console.WriteLine();}}static void SolveQueens(int n, int[] queens, int index, List<int[]> solutions){if (index == n){solutions.Add([.. queens]);return;}for (int i = 0; i < n; i++){if (CanPlaceQueen(queens, index, i)){queens[index] = i;SolveQueens(n, queens, index + 1, solutions);}}}static bool CanPlaceQueen(int[] queens, int index, int col){for (int i = 0; i < index; i++){if (queens[i] == col || Math.Abs(queens[i] - col) == index - i){return false;}}return true;}}
}

        在这个示例中,使用一个整数数组queens来表示棋盘上皇后的位置。queens数组的每个元素表示对应行上皇后的列位置。

        使用递归函数SolveQueens来解决八皇后问题。该函数接受当前皇后的位置、当前行号和已找到的解作为参数。在递归过程中,尝试在每一列上放置皇后,并检查是否满足问题的约束条件。如果满足,则将皇后放置在当前行的对应列上,并继续递归处理下一行。如果当前行的所有列都满足约束条件,则表示找到一个解,并将解添加到已找到的解列表中。

        函数CanPlaceQueen用于检查在给定位置放置皇后是否满足约束条件。它接受棋盘大小、当前皇后的位置、当前行号和当前列号作为参数。在函数中,遍历当前行号之前的行,检查当前列号是否已经放置了皇后,或者当前行和列上的皇后是否在同一条对角线上。如果满足任一条件,则表示不能在当前位置放置皇后。

        在Main函数中,输出找到的解决方案。对于每个解决方案,遍历8行8列,如果当前列是皇后的位置,则输出"Q",否则输出"."。

(4)回溯法(Backtracking):

        该方法通过递归的方式尝试所有可能的皇后位置。算法步骤如下:

  • 选择一个空的棋盘。
  • 选择一个皇后,将其放置在棋盘的第一行的任意一列。
  • 选择下一个皇后,将其放置在下一行的任意一列,但不能与第一个皇后位于同一列或同一对角线上。
  • 重复步骤3,直到所有的皇后都被放置在棋盘上。
// 八皇后算法_回溯法
namespace _144
{class Program{#region 八皇后算法/// <summary>/// 解决八皇后问题/// </summary>/// <param name="size">皇后数量</param>static void QueenArithmetic(int size){int[] Queen = new int[size];//每行皇后的位置int y, x, i, j, d, t = 0;y = 0;Queen[0] = -1;while (true){for (x = Queen[y] + 1; x < size; x++){for (i = 0; i < y; i++){j = Queen[i];d = y - i;//检查新皇后是否能与以前的皇后相互攻击if ((j == x) || (j == x - d) || (j == x + d))break;}if (i >= y)break;     //不攻击}if (x == size)     //没有合适的位置{if (0 == y){Console.WriteLine("Over");        //回溯到了第一行break;     //结束}Queen[y] = -1; //回溯y--;}else{Queen[y] = x;   //确定皇后的位置y++;            //下一个皇后if (y < size)Queen[y] = -1;else{Console.WriteLine("\n" + ++t + ':');//所有的皇后都排完了,输出for (i = 0; i < size; i++){for (j = 0; j < size; j++)Console.Write(Queen[i] == j ? 'Q' : '*');Console.WriteLine();}y = size - 1;//回溯}}}Console.ReadLine();}#endregionstatic void Main(string[] args){ArgumentNullException.ThrowIfNull(args);int size = 8;           //皇后数QueenArithmetic(size);}}
}

相关文章:

C#八皇后算法:回溯法 vs 列优先法 vs 行优先法 vs 对角线优先法

目录 1.八皇后算法&#xff08;Eight Queens Puzzle&#xff09; 2.常见的八皇后算法解决方案 &#xff08;1&#xff09;列优先法&#xff08;Column-First Method&#xff09;&#xff1a; &#xff08;2&#xff09;行优先法&#xff08;Row-First Method&#xff09;&a…...

springboot整合swagger,postman,接口规范

一、postman介绍 1.1概述 工具下载 Postman&#xff08;发送 http 请求的工具&#xff09; 官网&#xff08;下载速度比较慢&#xff09;&#xff1a;Download Postman | Get Started for Free 网盘下载&#xff1a;百度网盘 请输入提取码 1.2Http 请求格式 请求地址请求方法状…...

029—pandas 遍历行非向量化修改数据

前言 在 pandas 中&#xff0c;向量化计算是指利用 pandas 对象的内置方法和函数&#xff0c;将操作应用到整个数据结构的每个元素&#xff0c;从而在单个操作中完成大量的计算。 但在一些需求中&#xff0c;我们无法使用向量化计算&#xff0c;就需要迭代操作&#xff0c;本例…...

相机安装位置固定后开始调试设备供电公司推荐使用方法

摄像头安装位置固定后开始调试 设备供电&#xff1a;无电源设备需要连接12V/2A电源并连接到摄像机的DC端口&#xff0c;而有电源的摄像机可以直接连接到220V电源。 连接设备&#xff1a;如果是有线连接&#xff0c;请使用网线将设备连接到电脑&#xff08;建议直接连接&#…...

AI视频批量混剪系统|罐头鱼AI视频矩阵获客

AI视频批量混剪系统助您轻松管理和编辑视频素材 如今&#xff0c;视频营销已成为企业推广的重要方式。为了满足用户对视频管理、发布和编辑的需求&#xff0c;《罐头鱼AI视频批量混剪系统》应运而生。这款智能化系统集成了多种功能&#xff0c;助您轻松管理和发布精彩视频内容…...

线程池学习-了解,自定义线程池

什么是线程池&#xff0c;这个池字是什么 线程池&#xff0c;主要利用池化思想&#xff0c;线程池&#xff0c;字符串常量池等 为什么要有一个线程池&#xff1f; 正常线程的创建&#xff1a;1&#xff0c;手动创建一个线程 2.给该线程分配任务&#xff0c;线程执行任务 3…...

CentOS7.9 安装SIPp3.6

epel里面的SIPp版本比较旧&#xff0c;先不要epel yum remove -y epel-release okay有很多CentOS软件&#xff0c;可以这样安装&#xff1a; 编辑 /etc/yum.repos.d/okay.repo&#xff0c;内容为&#xff1a; [okay] nameExtra OKay Packages for Enterprise Linux - $basearc…...

Java零基础入门-LinkedHashMap集合

一、本期教学目标 学习LinkedHashMap集合的概念及特点。学习LinkedHashMap存储结构。学习LinkedHashMap集合常用方法及示例代码演示。 二、正文 1、概述 我们学习了map接口之HashMap集合&#xff0c;今天我们要来学习map接口的另一个实现类-LinkedHashMap&#xff0c;不知道…...

LRC转SRT

最近看到一首很好的英文MTV原版&#xff0c;没又字幕&#xff0c;自己找字幕&#xff0c;只找到LRC&#xff0c;ffmpeg不支持LRC&#xff0c;网上在线转了SRT。 Subtitle Converter | Free tool | GoTranscript 然后用 ffmpeg 加字幕 ffmpeg -i LoveMeLikeYouDo.mp4 -vf sub…...

mybatis源码阅读系列(二)

前言 上一篇文章mybatis源码阅读系列&#xff08;一&#xff09;介绍了mybatis和原生jdbc的区别&#xff0c;并通过代码展示了两者的运行过程和结果&#xff0c;下面让我们继续详细了解下mybatis的执行过程&#xff1b; package com.wyl.mybatis.service;import com.wyl.mybat…...

【Web开发】CSS教学(超详细,满满的干货)

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【Web开发】CSS教学(超详细,满满的干货) &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 CSS一. 什么是CSS?1.1 基本语法规范1.2 引入方式1.3 规范 二. CSS选…...

系列学习前端之第 5 章:学习 ES6 ~ ES11

1、什么是 ECMAScript ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。 从第 6 版开始&#xff0c;发生了里程碑的改动&#xff0c;并保持着每年迭代一个版本的习惯。 ES62015年&#xff0c;ES72016年&#xff0c;ES82017年&#xff0c;ES92018年&#…...

Linux学习(4)——使用编辑器

1.gedit编辑器 简单易懂&#xff0c;依赖图形界面。可以使用ctrlc ctrlv等快捷键&#xff0c;ctrls进行保存&#xff0c;与windows系统中相类似。 2.vi/vim编辑器 vi/vim可以直接通过控制台的终端完成文本的编辑&#xff0c;不依赖图形界面&#xff0c;使用范围更广。它的编辑…...

简单函数_短信计费

任务描述 用手机发短信&#xff0c;一条短信资费为0.1元&#xff0c;但限定一条短信的内容在70个字以内&#xff08;包括70个字&#xff09;。如果你一次所发送的短信超过了70个字&#xff0c;则会按照每70个字一条短信的限制把它分割成多条短信发送。假设已经知道你当月所发送…...

centos命令history设置记录10000行

今天在操作服务器的时候&#xff0c;用history查看操作记录的时候&#xff0c;发现只能查看10条&#xff0c;这样不行啊&#xff0c;我想查看所有人对服务器操作的命令。 [rootbogon ~]# history解决办法&#xff1a; #1、找到/etc/profile文件中的histsize 把10改成10000 […...

SpringBoot打造企业级进销存储系统 第七讲

Transientprivate String roles; // 所拥有的角色package com.java1234.entity;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import javax.p…...

1.实用Qt:解决绘制圆角边框时,圆角锯齿问题

目录 问题描述 解决方案 方案1&#xff1a; 方案2&#xff1a; 结果示意图 问题描述 做UI的时候&#xff0c;我们很多时候需要给绘制一个圆角边框&#xff0c;初识Qt绘制的童鞋&#xff0c;可能绘制出来的圆角边框很是锯齿&#xff0c;而且粗细不均匀&#xff0c;如下图&…...

JavaWeb08-Filter和Listener

目录 一、Filter 1.概述 2.作用 3.快速入门 4.执行流程 5.拦截路径配置 6.拦截器链&#xff08;多个过滤器&#xff09; 7.登录验证 二、Listener&#xff08;了解即可&#xff09; 1.概述 2.主要作用 3.分类 4.快速入门 一、Filter 1.概述 Filter 表示过滤器&am…...

关于ClickHouse的一些小技巧

关于ClickHouse的一些小技巧 设置变量 set param_nameAlex; select {name:String};projection的使用 基于projection&#xff08;投影&#xff09;的优化需要打开开关optimize_use_projections。ClickHouse里的projection是物化的&#xff0c;也就是说数据会复制存一份。 Pr…...

有来团队后台项目-解析7

sass 安装 因为在使用vite 创建项目的时候&#xff0c;已经安装了sass&#xff0c;所以不需要安装。 如果要安装&#xff0c;那么就执行 npm i -D sass 创建文件 src 目录下创建文件 目录结构如图所示&#xff1a; reset.scss *, ::before, ::after {box-sizing: border-…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...