这道题其实单纯使用DFS实现并不难,在函数里面加一个转弯次数的形参就行。刚拿到这道题我确实也是这么做的。
但是把代码提交之后出现了DFS很常见的问题——超时,后来在讨论区发现大部门AC的代码都是使用的BFS+优先队列,因为DFS都写出来了就不想改了,再说也有用DFS成功AC的呀。看了大牛的代码知道加一个数组进行剪剪枝就行。
#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
int to[4][2]={1,0,-1,0,0,1,0,-1};
char map[105][105];
int turn[105][105];
int sx,sy,ex,ey,swerve,nowtime;
bool endn=false;
int m,n;
void dfs(int x,int y,int flag){
if(nowtime>swerve) return;
if(x==ex&&y==ey){
endn=true;
}
if(endn) return;
//cout<<x<<" "<<y<<" "<<map[x][y]<<endl;
map[x][y]='*';
for(int i=0;i<4;i++){
int xn=x+to[i][0],yn=y+to[i][1];
if(map[xn][yn]!='.') continue;
if(turn[xn][yn]<turn[x][y]) continue; //剪枝!!!!如果到达点xn,yn时之前有到达过,并且转弯次数少于本次时,剪去
if(i<2){
if(flag==1||flag==0){
turn[xn][yn]=turn[x][y];
dfs(xn,yn,1);
}else{
nowtime++;
turn[xn][yn]=turn[x][y]+1; //剪枝数组值的改变
dfs(xn,yn,1);
nowtime--;
}
}else{
if(flag==-1||flag==0){
turn[xn][yn]=turn[x][y];
dfs(xn,yn,-1);
}else{
nowtime++;
turn[xn][yn]=turn[x][y]+1;
dfs(xn,yn,-1);
nowtime--;
}
}
}
map[x][y]='.';
}
int main()
{
int t;
cin>>t;
while(t--){
endn=false;
memset(map,0,sizeof(map));
memset(turn,999999,sizeof(turn)); //初始化剪枝数组要无限大,因为后面就是要筛选转弯次数少的路。
nowtime=0;
cin>>m>>n;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++){
cin>>map[i][j];
}
//cout<<map[2][1]<<endl;
cin>>swerve>>sy>>sx>>ey>>ex;
turn[sx][sy]=0;
dfs(sx,sy,0);
if(endn) cout<<"yes"<<endl;
else{
cout<<"no"<<endl;
}
}
return 0;
}