描述:
从某位置可以向八个方向移动,不可以移动到障碍,不可以穿过夹缝移动,还有机关是按顺序触发,走到机关所在的格子会自动触发机关!
- 起点可能是机关,不是第一个机关的话输出-1;
- 机关按顺序触发的,触发第i个机关时,不可以通过第j个机关所在的格子(i< j);
思路:
对起点进行特判,不满足直接输出-1;对于暂时不能走的机关标记为true,表示为已走过就可以啦~
代码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int Max_n=110;
int t,n,m,k;
struct Node{
int x,y,d;
Node(int xx,int yy,int dd):x(xx),y(yy),d(dd){}
};
char s[Max_n][Max_n];
bool vis[Max_n][Max_n];
int pos[10][2];
int dx[8]={0,0,1,-1,-1,-1,1,1};
int dy[8]={1,-1,0,0,1,-1,-1,1};
int bfs(int x1,int y1,int k){
queue<Node>que;
que.push(Node(x1,y1,0));
vis[x1][y1]=1;
if(x1==pos[k][0]&&y1==pos[k][1])return 0; //起点为第一个机关
while(!que.empty()){
Node node=que.front();que.pop();
int x=node.x,y=node.y,d=node.d;
if(x==pos[k][0]&&y==pos[k][1])return d;
for(int i=0;i<8;i++){
int X=x+dx[i],Y=y+dy[i];
if(!vis[X][Y]&&s[X][Y]=='.'&&(s[X][y]=='.'||s[x][Y]=='.')){
vis[X][Y]=1;
que.push(Node(X,Y,d+1));
}
}
}
return -1;
}
int main()
{
scanf("%d",&t);
while(t--){
memset(s,0,sizeof(s));
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
int x,y;
scanf("%d%d",&x,&y);
for(int i=0;i<k;i++)
scanf("%d%d",&pos[i][0],&pos[i][1]);
int sum=0;
bool flag=0;
for(int i=0;i<k;i++){
memset(vis,0,sizeof(vis));
for(int j=i+1;j<k;j++)
vis[pos[j][0]][pos[j][1]]=1; //还不能访问的机关置为true
if(vis[x][y]){flag=1;break;} //起点不为空地或第一个机关
int k=bfs(x,y,i);
if(k==-1){flag=1;break;}
sum+=k;
x=pos[i][0];y=pos[i][1];
}
if(flag)printf("-1\n");
else printf("%d\n",sum);
}
return 0;
}