内部DFS题,此题也可用BFS来做。
#include <iostream>
using namespace std;
const int N = 25;
int r, s, ans;
char g[N][N];
bool st[26];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
void dfs(int x, int y, int step)
{
st[g[x][y] - 'A'] = true;
for (int i = 0; i < 4; i ++ )
{
int a = x + dx[i], b = y + dy[i]; //判断下个点在范围内且没有走过
if (a >= 0 && a < r && b >= 0 && b < s && !st[g[a][b] - 'A'])
{
st[g[a][b] - 'A'] = true;
dfs(a, b, step + 1);
st[g[a][b] - 'A'] = false; //恢复现场
}
}
ans = max(ans, step); //取最大步数
}
int main()
{
cin >> r >> s;
for (int i = 0; i < r; i ++ ) cin >> g[i];
dfs(0, 0, 1); //起点横坐标,起点纵坐标,当前经过的点数量
cout << ans << endl;
return 0;
}
各位大佬们,请问这里为什么需要回复现场呀
int a = x + dx[i], b = y + dy[i]; //判断下个点在范围内且没有走过
这里为什么不能写成,x = x + dx[i], y = y + dy[i]; 呢?
是这样的,dfs()里面的for循环要朝四个方向遍历四次,我们每次都要用两个新变量
a
和b
来存放下一步的坐标。如果我们不采用新变量,还是用这种写法,那么四次循环下来,这段代码就执行了四次,x与y的值已经加得面目全非了,所以正确的做法是每个循环都声明新的坐标变量。
for中,每一个循环,不是走到最后, 才会进出下一个循环的吗?
是的,但是每个循环都会改变x与y的值,一直改变了四次,你可以模拟一下。设初始时
x=1,y=1
,则是不是发现不太对了。
若初始时
x=1,y=1
,我们期望遍历的坐标应该如下:问一下 st[g[x][y] - ‘A’] = true;为什么要写在for循环外面呢
写循环里面咋不对呢
是这样的,dfs()函数的作用是:
1. 将当前字母的状态设置为已使用;
2. 尝试往当前字母的上下左右四个方向推进。
代码
的目的是实现第一个步骤,故不能放到循环中。
我明白你的意思了,你想把这行写在for循环里面,其实无论如何这行都是没有必要写在for循环里面的,参考下面的代码:
直接在
main
函数中初始化,甚至可以省略掉这一行。呜呜呜非常抱歉!!我复制错代码片段了【我真是个废物】
我其实是想问这个来着
ans = max(ans, step);
再次抱歉【逃】
我试了下放循环里面也是可以的,没有报错,你可以把代码贴出来,我看看是哪里的问题。
放到循环里面 样例 答案就变成了 5
有劳啦【捂脸
是这样的,这行代码能放到
for
循环里面,但是不能放到if
语句里面,如果放在if
语句里面,你会发现结果永远比正确答案少1。这是因为只有进入if
语句中的dfs()
递归以后step
的值才会取到最大,你在递归之前就先取了max
值,所以只能取到最大值-1
。试想,如果代码按照你这样写的话,最后一层递归时是不会执行
这一行代码的。因为当前点就是最后一个节点,从最后一个节点出发无法前往它的相邻节点,故
if
语句的条件为假,不能进入if
语句,即不能执行这行代码。!!!我悟了。
谢谢解答!!