iis服务器助手广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++回溯法怎么应用
  • 863
分享到

C++回溯法怎么应用

2023-06-30 16:06:17 863人浏览 安东尼
摘要

本文小编为大家详细介绍“c++回溯法怎么应用”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++回溯法怎么应用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。回溯1实验题目:n皇后题目描述:N皇后的排列,每行一个

本文小编为大家详细介绍“c++回溯法怎么应用”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++回溯法怎么应用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

回溯1

实验题目:n皇后

题目描述:

N皇后的排列,每行一个不冲突;N<=13。

输入要求:

一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的

输出要求:

前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

解的输出顺序为从上到下从左到右,小的优先输出

实验代码及注释:

#include<bits/stdc++.h>using namespace std;int q[15] = { 0 }; //记录n个皇后的摆放位置// 下标为行,数组元素为列int sum = 0;int n;void queen(int i){int j;int col, flag; if (i == n + 1)//所有的行全部走完,即成功找到一种解法{sum++;if (sum <= 3) // 输出前三行结果{for (j = 1;j <= n;j++){if (j == n)cout << q[j] << endl;elsecout << q[j] << " ";}}return;}else{for (col = 1;col <= n;col++)//遍历i行的每一列{flag = 1; // 假定棋子可放在i行col列for (j = 1;j < i;j++)//n遍历前i行是否符合{if (col == q[j] || i - col == j - q[j] || i + col == j + q[j]){flag = 0; //与前面棋子发生冲突break;}}if (flag == 1)//未与前面棋子发生冲突{q[i] = col;queen(i + 1);//遍历下一行}}}}int main(void){cin >> n;memset(q, -1, sizeof(q)); //初始化棋子,-1表示未放上棋盘queen(1); //从第一行开始遍历cout << sum << endl;return 0;}

算法分析与知识点:

本题采用回溯算法思想来解决N皇后问题,这里用一个q[N]数组来记录棋子摆放情况:

算法开始, 清空棋盘,当前行设为第一行,当前列设为第一列

在当前行,当前列的位置上判断是否满足条件(即保证经过这一点的行,列与斜线上都没有两个皇后),若不满足,跳到第4步

在当前位置上满足条件的情形:

  • 在当前位置放一个皇后,若当前行是最后一行,记录一个解;

  • 若当前行不是最后一行,当前行设为下一行, 当前列设为当前行的第一个待测位置;

  • 若当前行是最后一行,当前列不是最后一列,当前列设为下一列;

  • 若当前行是最后一行,当前列是最后一列,回溯,即清空当前行及以下各行的棋盘,然后,当前行设为上一行,当前列设为当前行的下一个待测位置;

  • 以上返回到第2步

在当前位置上不满足条件的情形:

若当前列不是最后一列,当前列设为下一列,返回到第2步;

若当前列是最后一列了,回溯,即,若当前行已经是第一行了,算法退出,否则,清空当前行及以下各行的棋盘,然后,当前行设为上一行,当前列设为当前行的

下一个待测位置,返回到第2步;

实验题目:符号三角形

题目描述:

符号三角形的 第1行有n个由“+”和“-”组成的符号 ,以后每行符号比上行少1个,2个同号下面是“+”,2个异号下面是“-” 。计算有多少个不同的符号三角形,使其所含“+” 和“-” 的个数相同。

输入要求:

整数n(n<=20)。

输出要求:

符合要求的符号三角形的个数。

实验代码及注释:

#include<bits/stdc++.h> using namespace std;int a[30][30] = { 0 };int n, sum = 0, sum1 = 0;void check() {int t = n, sum2 = 0;while (t--) {for (int i = 1;i <= t;i++) {a[t][i] = 1 - (a[t + 1][i] + a[t + 1][i + 1]) % 2;  // 递推第t层i列的符号if (a[t][i])//若为+sum2++;}}if (2 * (sum1 + sum2) == (n * (n + 1) / 2)) //记录+总数是否为符号总数的一半sum++;}void dfs(int x) {  // x表示考虑顶层第x个位置的符号for (int i = 0;i < 2;i++) {//0=>-;1=>+if (i)sum1++; // 记录顶层+的数量a[n][x] = i;if (x == n)//考虑完顶层的一种符号摆放,进行检查check();elsedfs(x + 1);if (i)sum1--; // 若上摆放为+,则+数量回退1}}int main(){cin >> n;if ((n * (n + 1) / 2) % 2 == 1) //判断符号总数奇偶性cout << 0 << endl;else {dfs(1);cout << sum << endl;}return 0;}

算法分析与知识点:

本题主要运用回溯的思想,这题的特点是不能输入元素,而且只要确定的顶层的n的符号的排列情况,就可以得到整个符号三角形的排列情况,因此只需要对符号三角形的顶层进行遍历就好了。题目中有要求+和-的数量要一样,所以符号三角形的符号总数要是偶数,否则解决方案数为0。

令0和1分别代表-和+,其他层在顶层确定后即确定了,不需要枚举。采用dfs对第一层的符号排列情况进行遍历,遍历完n后就可得到答案。

回溯 堂练

实验题目:森林迷宫

题目描述:

一天Luna在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n * n的格点组成,每个格点只有2种状态:^ 和 # ;前者表示可以通行后者表示不能通行。当Luna处在某个格点时,她只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Luna想要从起点A走到终点B(中途不能走出迷宫)。如果起点或者终点有一个不能通行(为#),则当做无法通行。

输入要求:

第1行是测试数据的组数k,后面跟着k组输入。

每组测试数据的第1行是一个正整数n (1 <= n <= 100),表示迷宫的规模是n * n的。

接下来是一个n * n的矩阵,矩阵中的元素为 . 或者 #。

再接下来一行是4个整数ar,ac,br,bc。表示A处在第ar行,第ac列,B处在第br行, 第bc列。注意坐标ar,ac,br,bc全部是从0开始计数的类似[1,4][5,6]被认为是覆盖了[1,6]。

输出要求:

YES或NO

实验代码及注释:

#include<bits/stdc++.h> using namespace std;char s[105][105]; // 记录地图int n, ha, la, hb, lb, dir[4][2] = { {0,-1},{0,1},{-1,0},{1,0} }, flag;//flag标记搜索完毕后是否能到达终点void dfs(int ha, int la){if (ha == hb && la == lb) // 判断是否达到终点{flag = 1;}if (flag) {cout << "YES" << endl;return;}for (int i = 0;i < 4;i++){int dx = ha + dir[i][0];int dy = la + dir[i][1];if (dx >= 0 && dx < n && dy >= 0 && dy < n && s[dx][dy] == '^'){s[dx][dy] = '#';//只走一次,每个方都要走一遍,只要连通,肯定能到终点dfs(dx, dy);}}}int main(){int k;cin >> k;while (k--){cin >> n;for (int i = 0;i < n;i++) for (int j = 0;j < n;j++) cin >> s[i][j];cin >> ha >> la >> hb >> lb;if (s[ha][la] == '#' || s[hb][lb] == '#') cout << "NO" << endl;//提前判断始点和终点是否符合要求else{flag = 0;dfs(ha, la); //dfs搜索路径if (flag == 0) cout << "NO" << endl;}}return 0;}

算法分析与知识点:

本采用深度优先的搜索方式来搜索全部路径,大致思路为:从当前点出发,往四个方位探寻找出所有与之相邻的且尚未被访问过的点,从中暂时先选取一个点作为当前点继续上述过程,直到到达目的地或者再也无法探寻到能前进的点,再返回。如果当前搜索的点到达了目标点,flag标记为true,返回即可。若所有能到达的点都搜索完了,flag仍为false,则无法到达。

实验题目:地图着色

题目描述:

给定图G=(V, E),需要为图G的各顶点着色,是否有一种着色法使G中相邻的两个顶点有不同的颜色?

输入要求:

第一行是顶点的个数n(2&le;n&le;10),颜色数m(1&le;m&le;n)。

接下来是顶点之间的连接关系:a b;表示a和b相邻。顶点从1开始计。

当a,b同时为0时表示输入结束。

输出要求:

输出着色方案总数和最少颜色数。如果无可行方案,颜色数为0。

实验代码及注释:

#include<bits/stdc++.h> using namespace std;#define N 10int n, sum = 0, m;int x[N + 1]; //记录可行解int g[N + 1][N + 1];//邻接矩阵int ans = N;int ok(int t)  // 判断当前层节点是否可行{    for (int j = 1; j <= n; j++)        if (g[t][j] == 1 && x[t] == x[j])            return 0;    return 1;}int num_m() {  //计算可行解中的颜色种类数    int ans = 0;    int temp[101] = { 0 };    for (int i = 1;i <= n;i++) {        temp[x[i]] = 1;    }    for (int i = 1;i <= 100;i++)        ans += temp[i];    return ans;}void back_track(int t){    int i;    if (t > n)    {        sum++; //找到可行解,总数+1        //for (i = 1; i <= n; i++)        //    printf("%d ", x[i]);        // printf("\n");        int xx = num_m();        if (xx < ans)            ans = xx;    }    else    {        for (int i = 1; i <= m; i++)// 遍历节点的每种颜色取值        {            x[t] = i;            if (ok(t))                back_track(t + 1);            x[t] = 0;        }    }}int main(){    cin >> n >> m; //n个顶点,m种颜色    int a, b;    cin >> a >> b;    while (!(a == 0 && b == 0)) { //构造邻接矩阵        g[a][b] = 1;        g[b][a] = 1;        cin >> a >> b;    }    back_track(1);    if (sum)        cout << sum << " " << ans << endl;    else        cout << 0 << " " << 0 << endl;    return 0;}

算法分析与知识点:

这个问题和八皇后还有求子集和等问题都具有类似之处,其核心在通过遍历找到所有的问题子集 ,但是在递归遍历的时候,都在加一个判断,将那些明显不满足条件的情况给直接排出,减少问题的规模,其实这类问题,在递归遍历的时候都是类似与对一颗树的便利每个节点相当走到此时的状态,然后再判断此时的状态是否能继续走下去,如果不能就将其回溯到上一个节点,避免浪费时间。

给定图g(v,e)和m种颜色,如果这个图不是m可着色,给出否定回答,是的话找出所有不同着色法。

分析:

用邻接矩阵表示图g,如果顶点i跟j之间有边,则g[i][j] = 1,否则g[i][j] = 0.用整数1,2,&hellip;,m表示m种颜色,顶点i的颜色用x[i]表示,所以x[1:n]是一种着色方案。

在算法traceback中,当i>n时,就是所有顶点都上了色,得到新的m着色方案,当前m着色方案总数sum增一,输出方案。

当i<n时,就是未着色完所有顶点,当前顶点i有x[i] = 1, 2&hellip;m种颜色可图,对于每种颜色由函数ok判断可行性,并用dfs对可行颜色搜索,或减去不可行方案。

读到这里,这篇“C++回溯法怎么应用”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网其他教程频道。

--结束END--

本文标题: C++回溯法怎么应用

本文链接: https://www.lsjlt.com/news/330134.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++回溯法怎么应用
    本文小编为大家详细介绍“C++回溯法怎么应用”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++回溯法怎么应用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。回溯1实验题目:n皇后题目描述:N皇后的排列,每行一个...
    99+
    2023-06-30
  • C#回溯与非回溯怎么实现
    这篇文章主要介绍“C#回溯与非回溯怎么实现”,在日常操作中,相信很多人在C#回溯与非回溯怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#回溯与非回溯怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-17
  • C++算法学习之回溯法的应用
    目录回溯1实验题目:n皇后实验题目:符号三角形回溯 堂练实验题目:森林迷宫实验题目:地图着色回溯1 实验题目:n皇后 题目描述: N皇后的排列,每行一个不冲突;N<=13。 输...
    99+
    2024-04-02
  • C++ 递归函数在回溯算法中的应用?
    递归函数在回溯算法中通过深度优先搜索决策树来解决问题:函数调用自身,探索决策树的分支。针对问题,函数会不断深入探索树状结构,并在做出错误决策后进行回溯。实战案例:八皇后问题中,函数通过递...
    99+
    2024-04-24
    递归函数 回溯算法 c++
  • C语言全排列回溯算法怎么用
    这篇文章主要介绍“C语言全排列回溯算法怎么用”,在日常操作中,相信很多人在C语言全排列回溯算法怎么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言全排列回溯算法怎么用”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-26
  • 回溯算法之怎么求组合
    本篇内容介绍了“回溯算法之怎么求组合”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!回溯算法大家是不是已经快...
    99+
    2024-04-02
  • c语言回溯全排列怎么实现
    可以使用递归的方式实现回溯法求全排列。具体步骤如下:1. 定义一个递归函数 `backtrack()`,该函数有两个参数:`nums...
    99+
    2023-09-08
    c语言
  • C++回溯算法中的全排列问题怎么解决
    本文小编为大家详细介绍“C++回溯算法中的全排列问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++回溯算法中的全排列问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、全排列全排列的特点...
    99+
    2023-07-05
  • C语言全排列回溯算法介绍
    目录前言算法思想完整代码实验效果总结前言 本博文源于最近学习的递归算法,递归中遇到一个问题全排列的问题,我看见回溯特别神奇,特此记录一下。对比一下深度优先搜索与广度优先搜索,个人感觉...
    99+
    2024-04-02
  • 教你怎么用Java回溯算法解数独
    目录一、题干二、思路三、代码分段演示四、完整代码一、题干 输入一个9*9二维数组表示数独,已经填入的数字用1-9表示,待填入的数字用0表示,试写一个算法解出数独并输出。 二、思路...
    99+
    2024-04-02
  • C++使用回溯法解决黄金矿工问题
    目录题目描述示例解题思路顺心的人大抵一样,坎坷的人各有各的坎坷。也只能坚持自我修行,等待自己的机遇。 题目描述 你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小...
    99+
    2024-04-02
  • C++回溯算法中组合的相关问题怎么解决
    这篇文章主要讲解了“C++回溯算法中组合的相关问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++回溯算法中组合的相关问题怎么解决”吧!回溯算法模板void backtracki...
    99+
    2023-07-05
  • 怎么在Java中利用回溯算法解数独
    本篇文章为大家展示了怎么在Java中利用回溯算法解数独,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、题干输入一个9*9二维数组表示数独,已经填入的数字用1-9表示,待填入的数字用0表示,试写一个...
    99+
    2023-06-15
  • PHP怎么用回溯算法求解子集问题
    本篇内容介绍了“PHP怎么用回溯算法求解子集问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!回溯算法实际上一个类似枚举的搜索尝试过程,主要...
    99+
    2023-06-20
  • PHP怎么使用回溯算法计算组合总和
    本篇内容介绍了“PHP怎么使用回溯算法计算组合总和”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!给定一个数组candidates和一个目标数...
    99+
    2023-06-20
  • C语言如何使用回溯法解八皇后问题
    这篇文章给大家分享的是有关C语言如何使用回溯法解八皇后问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。八皇后问题(N皇后问题)的回溯法求解一、问题描述在一个国际象棋棋盘上放置八个皇后,使得任何两个皇后之间不相互...
    99+
    2023-06-22
  • C++ 函数递归详解:回溯法中的递归
    c++++ 函数递归详解:递归是函数调用自身的一种技术,在回溯法等算法中很有用。回溯法是通过系统地尝试所有解决方案并回溯到死胡同时来解决问题的。数独求解是递归函数在回溯法中实际应用的例子...
    99+
    2024-05-03
    c++ 回溯法 函数递归
  • C++回溯算法中子集问题如何解决
    这篇文章主要介绍了C++回溯算法中子集问题如何解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++回溯算法中子集问题如何解决文章都会有所收获,下面我们一起来看看吧。一、子集子集问题与其它问题最大的不同就是:...
    99+
    2023-07-05
  • C++回溯算法中子集问题分析探讨
    目录一、子集二、子集II三、递增子序列 一、子集 子集问题与其它问题最大的不同就是:每次递归,不止考虑叶子节点,而是考虑所有节点! 体现在代码上,就是每次递归都先result.pus...
    99+
    2023-03-15
    C++回溯算法子集 C++回溯算法 C++子集问题
  • C++回溯算法深度优先搜索举例分析
    目录扑克牌全排列员工的重要性图像渲染被围绕的区域岛屿数量电话号码的字母组合组合总数活字印书N皇后扑克牌全排列 假如有编号为1~ 3的3张扑克牌和编号为1~3的3个盒子,现在需要将3张...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作