欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > 1219:马走日

1219:马走日

2025/3/11 15:39:44 来源:https://blog.csdn.net/2401_88475903/article/details/145655240  浏览:    关键词:1219:马走日

题目要求在给定n×m大小的棋盘,以及马的初始位置(x,y)的情况下,要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。

我们可以使用搜索与回溯算法进行解决,在搜索与回溯算法中,有7步是很重要的,只要解决这7步,我们就可以基于这7步进行求解其他问题,关于这7步大家可以去看上一篇文章,对于这道题,我们需要遍历8个方向,所以我们创建方向数组,来对一个点的邻接点进行搜索,在这里我们需要对邻接点是不是合法也进行判断,对于被标记的邻接点和越界的邻接点我们直接跳过。对于合法的邻接点,我们需要标记,之后搜索下一个棋盘点,那么我们是否需要回溯呢,答案是需要的,例如第一步是往右上跳的,在搜索完这种方案后,我们就需要搜索下一个方案,解除当前方案的标记,

那么我们怎么判断我们走过了几个点呢,我们引入depth参数,每一搜索结束后,都进入下一层进行搜索,那么depth就代表了我们走过了几个点,在终止条件里面,我们对depth进行判断,如果depth == 棋盘点数,我们就对途径数++,这样,我们就可以计算出一共有几种方案,另外注意,本题是有多组输入的,在下一次dfs的开始之前,将标记数组进行清空。

#include <iostream>
#include <cstring>using namespace std;int t ,n, m, x, y,cnt;
bool vis[200][200];int dx[] = {-2,-2,-1,-1,1,1,2,2};
int dy[] = {1,-1,2,-2,2,-2,-1,1};void dfs(int x,int y,int depth) {if (depth == n * m) {cnt++;return;}vis[x][y] = 1;for (int i = 0; i < 8;i++) {int bx = x + dx[i], by = y + dy[i];if (bx < 0 || bx >= n || by < 0 || by >= m) continue;if (vis[bx][by]) continue;vis[bx][by] = 1;dfs(bx, by, depth + 1);vis[bx][by] = 0;}
}int main() {cin >> t;while (t--) {cnt = 0;memset(vis, 0, sizeof vis);cin >> n >> m >> x >> y;vis[x][y] = 1;dfs(x,y,1);vis[x][y] = 0;cout << cnt <<endl;}return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词