这道题其实单纯使用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; }