这题真是坑啊. . . . .
思路比较特别:
每次储存转折一次的所有点(4个方向)并标记,然后从这些点中依次储存转折一次的所有点,这样就把最短转折标记了
注意事项:
1 尼玛这个题是先输入y坐标再输入x坐标的
2 如果碰到某个点被标记了,那么应该跳过它,比如下面这个样例数据:
0 0 0 0 0 2
0 6 5 7 0 4
0 2 0 0 0 0
0 1 0 4 0 8
3 0 0 7 3 9
输入为 2 1 5 5 5
代码如下:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int n,m,k,sx,sy,ex,ey,visit[105][105];
char map[105][105];
struct node {
int x;
int y;
int turn;
};
bool bfs(){
queue<node>q;
while(!q.empty())q.pop();
node d,D;
int move[4][2]={0,1, 1,0, 0,-1, -1,0};
d.x=sx;d.y=sy;d.turn=0;
q.push(d);
while(!q.empty()){
d=q.front();
q.pop();
if(d.x==ex && d.y==ey )return true;
for(int i=0;i<4;i++){
D.x=d.x+move[i][0];
D.y=d.y+move[i][1];
D.turn=d.turn+1;
while(D.x>=1 && D.y>=1 && D.x<=n && D.y<=m && map[D.x][D.y]=='.' && D.turn<=k){
if(!visit[D.x][D.y]){
// cout<<D.x<<" "<<D.y<<endl;
visit[D.x][D.y]=D.turn;
q.push(D);
}
D.x+=move[i][0];
D.y+=move[i][1];
}
}
}
return false;
}
int main(){
int test;
cin>>test;
while(test--){
memset(visit,0,sizeof(visit));
memset(map,0,sizeof(map));
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>map[i][j];
}
}
cin>>k>>sy>>sx>>ey>>ex;
k++;
// cout<<"**"<<k<<endl;
if(bfs())cout<<"yes\n";
else cout<<"no\n";
/*for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<visit[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;*/
}
}