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

Posted jiamian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计蒜客 蒜头君回家(有条件的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<cstdio>
 2 #include<queue>
 3 #include<cstring>
 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<node> 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
",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<n;i++) {
49         scanf("%s",mat[i]);
50         for(int j=0;j<m;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 }

 

 

-

以上是关于计蒜客 蒜头君回家(有条件的BFS)的主要内容,如果未能解决你的问题,请参考以下文章

计蒜客--蒜头君开公司

61计蒜客 动态规划基础 蒜头君的城堡之旅

计蒜客 蒜头君的数轴

计蒜客习题 蒜头君的猜想(埃氏筛)

计蒜客习题蒜头君运送宝藏

线段树|计蒜客:斑点蛇-区间和