华为OD机试题库《C++》限时优惠 9.9
华为OD机试题库《Python》限时优惠 9.9
华为OD机试题库《JavaScript》限时优惠 9.9
针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。
看不懂有疑问需要答疑辅导欢迎私VX: code5bug
题目描述
Jungle 生活在美丽的蓝鲸城,大马路都是方方正正,但是每天马路的封闭情况都不一样。 地图由以下元素组成:
- ”.” — 空地,可以达到;
- ” * ” — 路障,不可达到;
- ”S” — Jungle的家;
- ”T” — 公司.
其中我们会限制Jungle拐弯的次数,同时Jungle可以清除给定个数的路障,现在你的任务是计算Jungle是否可以从家里出发到达公司。
输入描述
输入的第一行为两个整数t,c(0 ≤ t,c ≤ 100),t代表可以拐弯的次数,c代表可以清除的路障个数。
输入的第二行为两个整数n,m(1 ≤ n,m ≤ 100),代表地图的大小。
接下来是n行包含m个字符的地图。n和m可能不一样大。
我们保证地图里有S和T。
输出描述
输出是否可以从家里出发到达公司,是则输出YES,不能则输出NO。
示例1
输入:
2 0
5 5
..S..
****.
T....
****.
.....
输出:
YES
示例2
输入:
1 2
5 5
.*S*.
*****
..*..
*****
T....
输出:
NO
说明:
该用例中,至少需要拐弯1次,清除3个路障,所以无法到达
题解
这道题目属于图的遍历问题,使用深度优先搜索(DFS)来求解。我们需要在给定的网格地图中,从起点
S
出发,找到一条路径到达终点T
,同时满足以下两个限制条件:
- 拐弯次数限制:路径中的拐弯次数不能超过给定的
t
次。- 路障清除限制:路径中可以通过清除路障(
*
)来通过,但清除的路障总数不能超过给定的c
个。解题思路
- DFS搜索:使用深度优先搜索遍历所有可能的路径。对于每一个位置,尝试向四个方向(上、下、左、右)移动。在DFS过程中,需要记录当前的位置、剩余的拐弯次数、剩余的清除路障次数以及当前的移动方向。这样可以避免重复计算相同的状态。
- 拐弯判断:每次移动时,如果方向与之前的方向不同,则消耗一次拐弯次数。
- 路障处理:如果当前位置是路障(
*
),则消耗一次清除路障次数。- 终止条件:到达终点
T
时返回成功;如果超出任何限制条件(拐弯次数或清除路障次数)则返回失败。
C++
// Author: code5bug
#include <bits/stdc++.h>
using namespace std;
int t, c, n, m;
vector<string> g;
int dirs[5] = {-1, 0, 1, 0, -1}; // 方向数组
/**
* @param r 行号
* @param c 列号
* @param left_t 剩余可以拐弯的次数
* @param left_c 剩余以清除的路障次数
* @param d 当前行走的方向 [1,4]
* @return 是否可以到达公司
*/
bool dfs(int r, int c, int left_t, int left_c, int d) {
if (r < 0 || c < 0 || r >= n || c >= m || left_t < 0 || left_c < 0) {
return false;
}
if (g[r][c] == 'T') {
return true;
}
for (int i = 1; i <= 4; i++) {
int nr = r + dirs[i];
int nc = c + dirs[i - 1];
int cost_t = (i == d) ? 0 : 1;
int cost_c = (g[r][c] == '*') ? 1 : 0;
if (dfs(nr, nc, left_t - cost_t, left_c - cost_c, i)) {
return true;
}
}
return false;
}
int main() {
cin >> t >> c >> n >> m;
g.resize(n);
int row = 0, col = 0;
for (int i = 0; i < n; i++) {
cin >> g[i];
for (int j = 0; j < m; j++) {
if (g[i][j] == 'S') {
row = i;
col = j;
}
}
}
bool result = false;
for (int d = 1; d <= 4; d++) {
if (dfs(row, col, t, c, d)) {
result = true;
break;
}
}
cout << (result ? "YES" : "NO") << endl;
return 0;
}
希望这个专栏能让您熟练掌握算法, 🎁🎁🎁。
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏