肥胖的牛牛
链接:https://ac.nowcoder.com/acm/problem/208246
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
每逢佳节胖三斤,牛牛在过去的节日里长胖了,连拐弯都困难,甚至会卡在门上,所以他很讨厌拐弯。给你一个N*N(2≤N≤100)的方格中,‘x’表示障碍,‘.’表示没有障碍(可以走),牛牛可以从一个格子走到他相邻的四个格子,但是不能走出这些格子。问牛牛从A点到B点最少需要转90度的弯几次。
输入描述:
第一行一个整数:N,下面N 行,每行N 个字符,只出现字符:‘.’,‘x’,‘A’,‘B’;表示上面所说的矩阵格子,每个字符后有一个空格。
输出描述:
一个整数:最少转弯次数。如果不能到达,输出-1
输入
3
. x A
. . .
B x .
输出
2
备注:
开始和结束时的方向任意。
题意: 这道题是一道典型的DFS,因为一看走迷宫啊什么的,不是DFS,就是BFS,但是因为我太菜,还不会熟练运用BFS,所以我只能用DFS拉(看到提交里面好多大佬都是用的BFS ,或者DFS+队列)。言归正传,这就是一个走迷宫,加上表示前一步方向的变量,和计算转弯次数的变量。
分析: 那么我们先把DFS的板子打好,然后我们根据题意,增加两个变量,此时我们在考虑如何判断转换方向的事情。依旧是判断边界条件,判断当前位置可不可以通过,如果可以,那么我们继续DFS前往下一个点,不断循环往复。但是最重要的一点就是,方向的先后顺序不能改变,如果改变就会一直超时。(DFS:深度优先搜索,不撞南墙不回头,一条路走到黑,如果走不动,就进行回溯)
代码上都有注释,下次再遇见希望我可以盲写出来,直接AC的那种。
#include<bits/stdc++.h>
using namespace std;
#define ios std::ios::sync_with_stdio(false);
const int inf = 0x7f7f7f7f;
int n;
int vis[200][200];
char a[150][150];
int ans;
int dir[4][2]{{1, 0},//这里的方向不能换,换了就超时
{0, 1},//是因为我们下面有一部是根据他的下标来判断是否转弯了
{0, -1},
{-1, 0}};
int check(int x, int y) {
if (x <= n && x >= 1 && y >= 1 && y <= n && a[x][y] != 'x')
return 1;
return 0;
}
void dfs(int x, int y, int sum, int state) {
if (a[x][y] == 'B') {
ans = min(ans, sum);
}
if(sum >= ans) return; ///这一句也不能省,省了也超时
for (int i = 0; i < 4; i++) { ///我的dfs步骤写的很繁杂,实验室的大佬就写的很简便又美观
int xx = x + dir[i][0];///下一步
int yy = y + dir[i][1];
if (check(xx, yy) && !vis[xx][yy]) {
if (state == -1) { ///这里肯定第一步啊
vis[xx][yy] = 1;
dfs(xx, yy, sum, i);
vis[xx][yy] = 0;
} else if (state != i && state + i != 3) {///判断是否转弯,看上面的方向数组就可以看明白了
vis[xx][yy] = 1;
dfs(xx, yy, sum + 1, i);
vis[xx][yy] = 0;
} else {
vis[xx][yy] = 1;
dfs(xx, yy, sum, i);
vis[xx][yy] = 0;
}
}
}
}
int main() {
ios
ans = inf;
cin >> n;
int x, y;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> a[i][j];
if (a[i][j] == 'A') {
x = i, y = j;
vis[i][j] = 1;
}
}
}
dfs(x, y, 0, -1);
if (ans == inf) cout << -1 << endl;
else cout << ans << endl;
return 0;
}
又是被鄙视的一天,被说那么久还做不出来一道题。芜湖。