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

算法设计与分析实验报告c++实现(N皇后问题、卫兵布置问题、求解填字游戏问题、图的m着色问题)

一.N皇后问题

基本原理和思路:
从一条路往前走,能进则进,不能进则退回来,换一条路再试。在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。
而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。

代码实现如下:

#include <iostream>
#include <cmath>
using namespace std;
//皇后的个数,方案数目
int n,sum=0;
//记录放置方案
int x[100];//不能这样定义int *x;
//用户递归求取方案
void Queen1(void);
void TraceBack(int);
void PrintMethod(void);
//检查这一皇后放置方案是否满足要求
int Place(int);int main()
{cout << "输入皇后个数:" << endl;cin>>n;Queen1();return 0;
}void Queen1(void)
{TraceBack(0);
}
void TraceBack(int r)
{int i;if(r>=n){PrintMethod();//这个函数的正确性还没有得到验证sum++;}else{for(i=0;i<n;i++){x[r]=i;//在下一行判断当前路是不可行的之后,进入同级的另外的路径if(Place(r))//先试探当前这条路是可行的,则进入下一步循环TraceBack(r+1);}}
}
void PrintMethod(void)
{int i,j;cout<<"第"<<sum<<"个方案\n";for(i=0;i<n;i++){for(j=0;j<n;j++){if(j==x[i])cout<<"1";elsecout<<"0";}cout<<endl;}
}
int Place(int r)
{int i;for(i=0;i<r;i++){if(x[r]==x[i] || abs(r-i)==abs(x[r]-x[i]))//在此处判断皇后走的下一步路是否可行,如果不可行性,return 0;return 0;}return 1;
}

分析:时间复杂度为O(n^n)

二.卫兵步列问题

基本原理和思路:初始令所有的 X [i, j]= 1, i =1,2, …… m , j =1,2, ……n . 算法从 (1,1 )开始直到 (m,n)为止, 搜索树是二叉树,有 m x n 层 . 每个结点对应一个陈列室位置,如果令 X [i, j]= 0 ,取消(i,j ) 位置的哨兵,进入左子树;否则进入右子树。在进入左子树时需要检查房间被监视的情况。 即当取消( i,j )位置的哨兵时,此位置及其上、下、左、右位置是否被监视。

代码实现如下:

#include<iostream>
#include<fstream>
#include<queue>using namespace std;
class Solve;class Node   //Node节点,用来存放搜索树的节点
{friend class Solve;
private:int i;    //当前要放置的新位置 横坐标:i 纵坐标:jint j;int robotNums;    //当前节点已经放置的哨兵数目int beenMonitored;   //当前已经被监视的房间数int** x;    //当前放置哨兵的地方   0表示没有,1表示放置了int** y;    //当前已经被监视的地方   0表示没有,1表示已经监视了int m;      //行int n;      //列public:Node();   //构造函数Node(int m, int n);   //构造函数,m、n是行列数Node(const Node& a);  //这个函数是用于heap的push,push会调用复制构造函数,因此必须自定义一个friend bool operator<(const Node& a, const Node& b);   //重载<,用于优先队列的使用Node& operator=(const Node& a)   //赋值运算符,懒得换位置了{if (x || y){for (int i = 0; i < m + 2; ++i){if (x){delete[] x[i];}if (y){delete[] y[i];}}delete[] x;delete[] y;x = NULL;y = NULL;}i = a.i;j = a.j;robotNums = a.robotNums;beenMonitored = a.beenMonitored;m = a.m;n = a.n;x = new int* [m + 2];y = new int* [m + 2];for (int i = 0; i < m + 2; ++i){x[i] = new int[n + 2];y[i] = new int[n + 2];for (int j = 0; j < n + 2; ++j){x[i][j] = a.x[i][j];y[i][j] = a.y[i][j];}}return *this;}~Node();   //用到了new,因此析构函数要重载,避免内存泄露};class Solve     //解决问题的类
{
private:priority_queue<Node> heap;    //优先队列heapint ans;     //答案所需要的哨兵数目int m;       //行列数int n;int** result;  //答案哨兵的排列顺序public:Solve();Solve(int m, int n);void run(ofstream& fcout);    //进行整个计算+输出void get_min();               //运用分支限界法,寻找最小值void print(ofstream& fcout);  //打印哨兵位置和数目void copy(int** x, int** y);  //将一个二维数组赋值给另一个void change(Node& tmp, int i, int j);   //生成子节点,同时将其添加到heap中
};int main()
{ifstream fcin;fcin.open("input.txt");if (!fcin.is_open()){cout << "文件 input.txt 未能打开" << endl;return -1;}int m, n;fcin >> m >> n;fcin.close();Solve solve(m, n);ofstream fcout;fcout.open("output.txt");if (!fcout.is_open()){cout << "文件 output.txt 未能打开" << endl;return -1;}solve.run(fcout);fcout.close();return 0;
}

分析:复杂度 W(n,m)=O(nm2)。

三. 求解填字游戏问题

  1. 基本原理和思路:从(0,0)开始向右搜索,搜到(3,0)结束
  2. 搜索时记录那些点被用过,下一个点一定是没有被用过的点,使用vis数组标记
  3. 退出条件:搜索到 x == 3时,即此时九个点都已经填了一遍值,输出填入的九个值
  4. 改点是否可以填入,是否合法:使用check函数来检查一下,由于是从左向右开始填起,所以相邻元素只需要考虑上和下两个方向,check函数加上判断边界的条件即可。
  5. 若该点合法,则填入该点,否则继续循环找一个可选点。
  6. 判断边界:即不能超出 3 * 3 的范围,到了最右边要进行换行,否则横坐标直接++即可!具体实现:if(y == 2) dfs(x + 1, 0); else dfs(x, y + 1);
  7. 最后取消标记,回溯上一个点,找下一种选择情况。

代码实现如下:

#include <iostream>using namespace std;int a[3][3], count;
bool vis[10];bool isprime(int n)
{for(int i = 2; i * i <= n; i++){if(n % i == 0) return false;}return true;
}bool check(int x, int y, int k)
{// 上 if(x - 1 >= 0 && !isprime(a[x - 1][y] + k)) return false;// 左 if(y - 1 >= 0 && !isprime(a[x][y - 1] + k)) return false;return true;
}void dfs(int x, int y)
{if(x == 3){for(int i = 0; i < 3; i++){for(int j = 0; j < 3; j++){cout << a[i][j] << " ";}cout << endl;}cout << endl;count ++;return;}for(int i = 1; i <= 10; i++){if(!vis[i] && check(x, y, i)){a[x][y] = i; vis[i] = true;if(y == 2) dfs(x + 1, 0);else dfs(x, y + 1);a[x][y] = 0; vis[i] = false;}}
}int main()
{dfs(0, 0);cout << "Total: " << count << endl;return 0;
}

分析:采用回溯法,即求全排列,时间复杂度O(n!)

四.求解图的m着色问题

基本原理和思路:MaxSum(i,j):从第i行j列到底边的最大数字之和
从最后一行开始递推,MaxSum(n,j)=D(n,j)//n行j列,MaxSum(n-1,j) = D(n-1,j) + max( MaxSum(n,j) , MaxSum(n,j+1) )
然后为了减少空间,不需要用二维数组来存储MaxSum(n,j)的值,只需要求MaxSum(n,j)的时候存储下一行MaxSum(n+1,j)的值就可以,然后计算完第n行的MaxSum之后再覆盖原来的第n+1行的MaxSum的值。

代码实现如下:

#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>using namespace std;const int N = 5;//图的顶点数
const int M = 3;//色彩数
class Color
{friend int mColoring(int, int, int **);
private:bool Ok(int k);void Backtrack(int t);int n,      //图的顶点数m,      //可用的颜色数**a,    //图的邻接矩阵*x;     //当前解long sum;   //当前已找到的可m着色方案数
};
int mColoring(int n,int m,int **a);
int main()
{int **a = new int *[N+1];for(int i=1; i<=N; i++){a[i] = new int[N+1];}cout<<"请输入图G的邻接矩阵:"<<endl;for(int i=1; i<=N; i++){for(int j=1; j<=N; j++){cin>>a[i][j];}cout<<endl;}cout<<"图G的着色方案如下:"<<endl;cout<<"当m="<<M<<"时,图G的可行着色方案数目为:"<<mColoring(N,M,a)<<endl;for(int i=1; i<=N; i++){delete[] a[i];}delete []a;
}void Color::Backtrack(int t)
{if (t>n){sum++;for (int i=1; i<=n; i++)cout << x[i] << " ";cout << endl;}else{for (int i=1; i<=m; i++){x[t]=i;if (Ok(t)) Backtrack(t+1);x[t]=0;}}
}bool Color::Ok(int k)// 检查颜色可用性
{for (int j=1; j<=n; j++){if ((a[k][j]==1)&&(x[j]==x[k])) //相邻且颜色相同{return false;}}return true;
}int mColoring(int n,int m,int **a)
{Color X;//初始化XX.n = n;X.m = m;X.a = a;X.sum = 0;int *p = new int[n+1];for(int i=0; i<=n; i++){p[i] = 0;}X.x = p;X.Backtrack(1);delete []p;return X.sum;
}

分析:时间复杂度是 O ( m ∗ n 2 ) O(m*n^2) O(mn2)

相关文章:

算法设计与分析实验报告c++实现(N皇后问题、卫兵布置问题、求解填字游戏问题、图的m着色问题)

一&#xff0e;N皇后问题 基本原理和思路&#xff1a; 从一条路往前走&#xff0c;能进则进&#xff0c;不能进则退回来&#xff0c;换一条路再试。在包含问题的所有解的解空间树中&#xff0c;按照深度优先搜索的策略&#xff0c;从根结点出发深度探索解空间树。当探索到某一…...

深入探索Linux中的libgdbus:GDBus库的应用和实现

引言 在Linux系统中&#xff0c;DBus是一种高效的进程间通信&#xff08;IPC&#xff09;机制&#xff0c;广泛应用于桌面环境和系统服务之间的通信。GDBus是基于GLib库的DBus实现&#xff0c;作为libgdbus的一部分提供。它旨在提供一种简洁、高效的方式来实现DBus通信。通过深…...

MacOS下Qt 5开发环境安装与配置

最近笔者在MacOS中使用Qt Creator开发Qt程序时遇到了一些问题&#xff0c;在网上查了不少资料&#xff0c;都没有找到解决方案&#xff0c;只有自己进行研究摸索了&#xff0c;今天晚上终于将目前遇到的问题全部解决了&#xff0c;特记录下来分享给大家。 笔者使用的是MacOS 1…...

jquery 实现倒计时

$(".tableText").click(function () { var time 60; var timer setInterval(function(){ time--; $(".tableText").text("&#xff08;"time"秒&#xff09;重发"); if(time0){ clearI…...

MYSQL 5.7重置root密码

Mysql 5.7重置root密码 如果您忘记了MySQL 5.7的root密码&#xff0c;可以通过以下步骤重置&#xff1a; 停止MySQL服务。在命令行中输入以下命令&#xff1a; systemctl stop mysqld启动MySQL服务并跳过授权表。在命令行中输入以下命令&#xff1a; mysqld_safe --skip-gra…...

博客永久链接与计数

概述 工欲善其事&#xff0c;必先利其器。 对自己的博客不好用不满意很久了&#xff0c;但是这几年太懒。想趁着放假弄一下吧&#xff0c;发现几年没动&#xff0c;版本升级后很多东西变了&#xff0c;折腾了一下午效果不太理想。先记录一下。 问题 博客链接中有中文&#x…...

基于 RisingWave 和 ScyllaDB 构建事件驱动应用

概览 在构建事件驱动应用时&#xff0c;人们面临着两大挑战&#xff1a;1&#xff09;低延迟处理大量数据&#xff1b;2&#xff09;实现流数据的实时摄取和转换。 结合 RisingWave 的流处理功能和 ScyllaDB 的高性能 NoSQL 数据库&#xff0c;可为构建事件驱动应用和数据管道…...

mysql8.0高可用集群架构实战

MySQL :: MySQL Shell 8.0 :: 7 MySQL InnoDB Cluster 基本概述 InnoDB Cluster是MySQL官方实现高可用读写分离的架构方案,其中包含以下组件 MySQL Group Replication,简称MGR,是MySQL的主从同步高可用方案,包括数据同步及角色选举Mysql Shell 是InnoDB Cluster的管理工具,用…...

GRE/MGRE详解

GRE GRE&#xff1a;通用路由封装&#xff0c;是标准的三层隧道技术&#xff0c;是一种点对点的隧道技术&#xff1b; 该技术可以实现不同的网络之间安全的访问&#xff1b; 如上&#xff1a;可以使用该技术搭建一条专线&#xff0c;实现公司A与分公司A1之间相互通信&#xf…...

蓝桥杯(填空题)

十四届 B组 日期统计&#xff08;暴力枚举&#xff09; 数据 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4 6 8 6 3 3 8 5 1 6 3 4 6 7 0 7 8 2 7 6 8 9 5 6 5 6 1 4 0 1 0 0 9 4 8 0 9 1 2 8 5 0 2 5 3…...

vim快捷指令

Vim是一款强大的文本编辑器&#xff0c;它提供了许多快捷指令来提高编辑效率。以下是一些常用的Vim快捷指令&#xff1a; 移动光标&#xff1a; h 向左移动一个字符j 向下移动一行k 向上移动一行l 向右移动一个字符w 跳到下一个单词的开头b 跳到前一个单词的开头e 跳到当前单词…...

LINUX 下IPTABLES配置详解

-t<表>&#xff1a;指定要操纵的表&#xff1b; -A&#xff1a;向规则链中添加条目&#xff1b; -D&#xff1a;从规则链中删除条目&#xff1b; -i&#xff1a;向规则链中插入条目&#xff1b; -R&#xff1a;替换规则链中的条目&#xff1b; -L&#xff1a;显示规则链中…...

CentOS 网卡ifcfg-eth0 ping不通外网(www.baidu.com)

1、如果确认好就直接激活网卡&#xff01; ifup eth0 2、慢慢找&#xff1a; cd /etc/sysconfig/network-scripts/ ls 找到你的网卡是啥&#xff0c;这里网卡是 ifcfg-eth0 执行1就好了&#xff01;...

【C++】类和对象②(类的默认成员函数:构造函数 | 析构函数)

&#x1f525;个人主页&#xff1a;Forcible Bug Maker &#x1f525;专栏&#xff1a;C 目录 前言 类的6个默认成员函数 构造函数 概念 构造函数的特性及用法 析构函数 概念 析构函数的特性及用法 结语 前言 本篇主要内容&#xff1a;类的6个默认成员函数中的构造函…...

【ZZULIOJ】1063: 最大公约与最小公倍(Java)

目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy 提示 code 题目描述 输入两个正整数&#xff0c;输出其最大公约数和最小公倍数。 输入 输入两个正整数n和m&#xff08;n,m<1000000)。输入保证最终结果在int范围内。 输出 输出两个整数&#xff0c;用空格…...

遍历列举俄罗斯方块的所有形状

以前玩俄罗斯方块的时候&#xff0c;就想过一个问题&#xff0c;为什么俄罗斯方块就这7种形状&#xff0c;还有没有别的形状&#xff1f;自己也在纸上画过&#xff0c;比划来比划去&#xff0c;确实就这几种形状。 继续思考一下&#xff0c;那假如是3个块组合的形状&#xff0…...

将Visio绘图导出PDF文件,使其自适应大小,并去掉导入Latex的边框显示

问题描述 将Visio绘图导成pdf文件&#xff0c;首先在Visio绘图如下&#xff1a; 如果直接导出或者另存为pdf文件&#xff0c;则会发现pdf文件是整个页面大小&#xff0c;而不是图片大小。而且在导入latex等排版工具现实时&#xff0c;会显示边框。 问题解决 1.调整Visio中的页…...

android支付宝接入流程

接入前准备 接入APP支付能力前&#xff0c;开发者需要完成以下前置步骤。 本文档展示了如何从零开始&#xff0c;使用支付宝开放平台服务端 SDK 快速接入App支付产品&#xff0c;完成与支付宝对接的部分。 第一步&#xff1a;创建应用并获取APPID 要在您的应用中接入支付宝…...

Mac 下 Python+Selenium 自动上传西瓜视频

背景 研究下 PythonSelenium 自动化测试框架&#xff0c;简单实现 Mac 下自动化批量上传视频西瓜视频并发布&#xff0c;分享给需要的同学&#xff08;未做过多的异常处理&#xff09;。 脚本实现 首先通过手工手机号登录&#xff0c;保存西瓜视频网站的 cookie 文件 之后加载…...

六:ReentrantLock —— 可重入锁

目录 1、ReentrantLock 入门2、ReentrantLock 源码解析2.1、构造方法&#xff1a;默认为非公平锁2.2、三大内部类2.2、lock()&#xff1a;加锁【不可中断锁】2.2.1、acquire() 方法 —— AQS【模板方法】2.2.2.1 tryAcquire() 方法 —— AQS&#xff0c;由子类去实现2.2.2.2. a…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...