祈祷中...

题意

一个地图,其中有一些守卫,他们的视线是一个直线,直到碰到障碍物,现在主角在 $\left(qx,qy\right)$,在地图上是 S,现在要去终点 $\left(zx,zy\right)$,不能出现在守卫视线中,问能否到达,若能,输出最小花费,若不能,输出 $-1$。

思路

首先处理一下守卫的问题,每找到一个守卫就将他视线内的直线变成 #,然后朴素 bfs,没什么好讲的,但是要注意,守卫的视线只能在 . 的方格内穿过,遇到其他方格会被挡住。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
template<typename P>
inline void read(P &x){
P res=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
res=res*10+ch-'0';
ch=getchar();
}
x=res*f;
}
int T=1;
char mapp[2020][2020];
int n,m;
int xx[4]={1,0,-1,0};
int yy[4]={0,-1,0,1};
map<char,int> fx;
bool vis[2020][2020];
bool pd[2020][2020];
void Init(int x,int y,int fx){
pd[x][y]=1;
int nx=x+xx[fx];
int ny=y+yy[fx];
if(nx>=1 && nx<=n && ny>=1 && ny<=m && mapp[nx][ny]=='.') Init(nx,ny,fx);
}
int qx,qy,zx,zy;
struct node{
int x,y,s;
};
void bfs(int x,int y){
queue<node> q;
q.push(node{x,y,0});
vis[x][y]=1;
while(!q.empty()){
int X=q.front().x;
int Y=q.front().y;
int S=q.front().s;
q.pop();
if(X==zx && Y==zy){
cout<<S<<endl;
exit(0);
}

for(int i=0;i<=3;++i){
int nx=X+xx[i];
int ny=Y+yy[i];
if(nx>=1 && nx<=n && ny>=1 && ny<=m && !vis[nx][ny] && (mapp[nx][ny]=='.' || mapp[nx][ny]=='G')){
vis[nx][ny]=1;
q.push(node{nx,ny,S+1});
}
}
}
}
signed main(){
read(n),read(m);
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
cin>>mapp[i][j];
if(mapp[i][j]=='S') qx=i,qy=j;
if(mapp[i][j]=='G') zx=i,zy=j;
}
}
fx['v']=0;
fx['<']=1;
fx['^']=2;
fx['>']=3;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(mapp[i][j]!='.' && mapp[i][j]!='S' && mapp[i][j]!='#' && mapp[i][j]!='G'){
int ff=fx[mapp[i][j]];
Init(i,j,ff);
}
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(pd[i][j]==1) mapp[i][j]='#';
}
}
bfs(qx,qy);
cout<<-1<<endl;
return 0;
}