这个月最后一天了,所以来一题。对于搜索题现在很多时候能写出来,但是不会优化,经常超时。这一题刚开始用BFS一直到是WA,然后用DFS终于不WA了,但是TLE了。想了很久以后,没有想到怎么处理,最终只能参考别人的思路了。每次看别人的思路都会有一种,幡然醒悟的感觉。都会感叹为什么自己就没想到。说多了都是泪啊。
下面来看看这一题的方法吧;
这一题其实转弯数处理特别难,我刚开始想到转弯怎么处理,但是遍历方式又不对。所以这一题,既要有一个好的转弯数处理,又要有一个正确的遍历方式,当然在本题中采用线性的遍历,是最佳方案。(之前一直没想到这种遍历方式,说多了都是泪啊)这样再与BFS相配合这道题就解决了。
至于DFS,现在我也不会,容我优化之后再看看。现在我的DFS老是超时,痛苦中。。。
下面是代码加注释:
#include <iostream>
#include <queue>
#include <cstring>
#define MAXN 100 + 10
using namespace std;
typedef struct{
int x,y,turn;
}coordinate;
int m,n,k;
queue<coordinate>Q;
coordinate start,goal;
char maze[MAXN][MAXN];
bool vis[MAXN][MAXN];
const int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; //位移参量
void Init(){ //初始化数值
memset(maze,0,sizeof(maze));
memset(vis,false,sizeof(vis));
}
bool Judge(int x,int y){ //能够访问该点的条件
if(x<=0||x>m||y<=0||y>n||maze[x][y]=='*')
return false;
return true;
}
bool BFS(){
coordinate now,next;
while(!Q.empty()) //队列初始化
Q.pop();
if(start.x==goal.x&&start.y==goal.y)
return true;
Q.push(start); //将起始点推入队列并标记
vis[start.x][start.y]=true;
while(!Q.empty()){
now = Q.front();
Q.pop();
for(int i=0;i<4;i++){
next.x = now.x + dx[i];
next.y = now.y + dy[i]; //进行四个方向遍历
while(Judge(next.x,next.y)){ //进行笔直的访问(不转弯)
if(!vis[next.x][next.y]){
next.turn = now.turn + 1;
vis[next.x][next.y] = true;
Q.push(next);
if(next.x==goal.x&&next.y==goal.y&&next.turn<=k)
return true;
}
next.x += dx[i];
next.y += dy[i];
}
}
}
return false;
}
int main(){
int T;
cin>>T;
while(T--){
cin>>m>>n;
Init();
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
cin>>maze[i][j];
cin>>k>>start.y>>start.x>>goal.y>>goal.x;
start.turn=-1; //因为第一次遍历会把转弯数多加一,所以将开始的值初始为-1
if(BFS())
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}