lanmengfei @ 2023-06-09 16:57:05
贴代码(用的深搜) :
#include<bits/stdc++.h>
using namespace std;
int n,m;
bool ans=0,book[105][105];
string s[105];
char c[105][105];
const int dis[][2]={
{0,0},
{1,0},
{-1,0},
{0,1},
{0,-1}
};
void dfs(int x,int y){
if(x==n and y==m){
ans=1;
return;
}
if(x>n or y>m){
ans=0;
return;
}
for(int i=0;i<5;i++){
int mx,my;
mx=x+dis[i][0],my=y+dis[i][1];
if(mx<1 or mx>n or my<1 or my>m){
continue;
}
if(c[mx][my]=='.' and book[mx][my]==0){
book[mx][my]=1;
dfs(mx,my);
//book[mx][my]=0;删的这一行
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>s[i];
for(int j=0;j<s[i].size();j++){
c[i][j+1]=s[i][j];
}
}
dfs(1,1);
cout<<(ans?"Yes":"No");
return 0;
}
by hellolin @ 2023-06-09 17:05:55
@lanmengfei 访问状态不应该置
by GloryYang @ 2023-06-09 17:20:56
会导致一个点遍历多次,卡在某个地方死循环,从而TLE,把那行删掉,每个点只遍历一次,就能过了
by lanmengfei @ 2023-06-13 22:05:01
@hellolin 是不是说去掉那一行就和广搜很相似了?
by code_1237 @ 2023-07-03 13:30:48
呜呜呜,我也是这个问题,但我还是不太很懂,有没有佬给我详细的说一下。
by lanmengfei @ 2023-07-05 13:30:53
@code_1237 我回去想了一下,其实大概是这样的
一开始在(1,1)
我们遍历4个方向,在这4个方向中,如果有符合条件的,把这个地方设为已遍历。
接下来再从这4个点开始遍历4个方向,就像是源点扩散一样,直到如果扩散到了(n,m)就停止。(由于不求最短路径,所以遇到无法遍历的点直接跳过,不用再次返回;更不需要广搜的队列实现,时间复杂度大大降低)
代码是这里:
for(int i=0;i<5;i++){
int mx,my;
mx=x+dis[i][0],my=y+dis[i][1];
if(mx<1 or mx>n or my<1 or my>m){
continue;
}
if(c[mx][my]=='.' and book[mx][my]==0){
book[mx][my]=1;
dfs(mx,my);
}
}
你可以回去画个图想一下,想通了就很好理解了(我也是这样的)
by code_1237 @ 2023-07-06 15:28:43
@lanmengfei 谢谢大佬十分感谢!!!!!!!!!