计蒜客 蒜头君回家(有条件的BFS)

计蒜客 蒜头君回家(有条件的BFS)

蒜头君要回家,但是他家的钥匙在他的朋友花椰妹手里,他要先从花椰妹手里取得钥匙才能回到家。花椰妹告诉他:“你家的钥匙被我复制了很多个,分别放在不同的地方。”

蒜头君希望能尽快回到家中,他需要首先取得任意一把钥匙,请你帮他计算出回家所需要的最短路程。

蒜头君生活的城市可以看做是一个 n×m 的网格,其中有道路有障碍,钥匙和家所在的地方可以看做是道路,可以通过。蒜头君可以在城市中沿着上下左右 4 个方向移动,移动一个格子算做走一步。

输入格式

第一行有两个整数 n,m。城市的地图是 n 行 m 列。(1≤n,m≤2000)

接下来的 n 行,每行 m 个字符,代表城市的地图。'.' 代表道路,'#' 代表障碍物,'S' 代表蒜头君所在的位置,'T' 代表蒜头家的位置,'P'代表钥匙的位置。除了障碍物以外,别的地方都可以通过。(题目保证蒜头君至少有一条路径可以顺利拿到钥匙并且回家)

输出格式

输出蒜头回家要走的最少步数,占一行。

样例输入

8 10

P.####.#P#

..#..#...#

..#T##.#.#

..........

..##.#####

..........

#####...##

###....S##

样例输出

21

bfs 的时候标记数组多开一维度表示是否已经取得了钥匙的状态。如果到达终点并且取得钥匙的状态被标记,bfs 结束。

所以我们需要把vis数组开成三维,第三个维度来标记是否拿到钥匙,也就是同一个点其实可以走两次,第一次是没拿到钥匙的时候,第二次是拿到钥匙的时候

1 #include

2 #include

3 #include

4 using namespace std;

5

6 int n,m;

7 char mat[2010][2010];

8 bool vis[2010][2010][2];

9 int dir[4][2]={1,0,-1,0,0,-1,0,1};

10

11 struct node{

12 int x,y,step,op;

13 node(){}

14 node(int _x,int _y,int _step,int _op):x(_x),y(_y),step(_step),op(_op){}

15 }st,key;

16

17 void bfs(node u) {

18 queue q;

19 q.push(u);

20 vis[u.x][u.y][0]=1;

21 while(!q.empty()) {

22 node f=q.front();

23 q.pop();

24 printf("x=%d y=%d step=%d op=%d\n",f.x,f.y,f.step,f.op);

25 if(mat[f.x][f.y]=='T'&&f.op) {

26 printf("%d",f.step);

27 return ;

28 }

29 for(int i=0;i<4;i++) {

30 int nx=f.x+dir[i][0];

31 int ny=f.y+dir[i][1];

32 if(vis[nx][ny][f.op]||nx<0||nx>=n||ny<0||ny>=m||mat[nx][ny]=='#') continue;

33 if(mat[nx][ny]=='P') {

34 q.push(node(nx,ny,f.step+1,1));

35 vis[nx][ny][1]=1;

36 }

37 else

38 {

39 q.push(node(nx,ny,f.step+1,f.op));

40 vis[nx][ny][f.op]=1;

41 }

42 }

43 }

44 }

45

46 int main() {

47 scanf("%d%d",&n,&m);

48 for(int i=0;i

49 scanf("%s",mat[i]);

50 for(int j=0;j

51 if(mat[i][j]=='S') {

52 st.x=i;

53 st.y=j;

54 st.step=0;

55 st.op=0;

56 }

57 }

58 }

59 bfs(st);

60 return 0;

61 }

-

Copyright © 2088 世界杯预选赛中国_1994年世界杯冠军是谁 - nywk120.com All Rights Reserved.
友情链接
Top