11I:变换的迷宫

总时间限制: 
1000ms
 
内存限制: 
65536kB
描述

你现在身处一个R*C 的迷宫中,你的位置用"S" 表示,迷宫的出口用"E" 表示。

迷宫中有一些石头,用"#" 表示,还有一些可以随意走动的区域,用"." 表示。

初始时间为0 时,你站在地图中标记为"S" 的位置上。你每移动一步(向上下左右方向移动)会花费一个单位时间。你必须一直保持移动,不能停留在原地不走。

当前时间是K 的倍数时,迷宫中的石头就会消失,此时你可以走到这些位置上。在其余的时间里,你不能走到石头所在的位置。

求你从初始位置走到迷宫出口最少需要花费多少个单位时间。

如果无法走到出口,则输出"Oop!"。

输入
第一行是一个正整数 T,表示有 T 组数据。
每组数据的第一行包含三个用空格分开的正整数,分别为 R、C、K。
接下来的 R 行中,每行包含了 C 个字符,分别可能是 "S"、"E"、"#" 或 "."。
其中,0 < T <= 20,0 < R, C <= 100,2 <= K <= 10。
输出
对于每组数据,如果能够走到迷宫的出口,则输出一个正整数,表示最少需要花费的单位时间,否则输出 "Oop!"。
样例输入
1
6 6 2
...S..
...#..
.#....
...#..
...#..
..#E#.
样例输出
7
 1 #include<iostream>
 2 #include<queue> 
 3 #include<cstring>
 4 using namespace std;
 5 int r, c, k;
 6 char a[105][105];
 7 bool visited[105][105][12];
 8 int dirx[4]={0,0,1,-1};
 9 int diry[4]={1,-1,0,0};
10 struct node{
11     int x, y, t;
12     node(int x_, int y_, int t_ = 0):x(x_),y(y_),t(t_){}
13 };
14 queue<node>q;
15 int main(){
16     int t;
17     cin>>t;
18     while(t--){
19         cin>>r>>c>>k;
20         int i, j, sx, sy;
21         memset(a, 0, sizeof(a));
22         memset(visited, 0, sizeof(visited));
23         while(!q.empty())q.pop();
24         for(i = 1; i <= r; i++)
25             for(j = 1; j <= c; j++){
26                 cin>>a[i][j];
27                 if(a[i][j]=='S'){
28                     sx = i; sy = j;
29                 }
30             }
31         q.push(node(sx,sy));
32         visited[sx][sy][0] = true;
33         bool flag = false;
34         while(!q.empty()){
35             node no = q.front();
36             q.pop();
37             int step = no.t;
38             if(a[no.x][no.y]=='E'){
39                 cout<<step<<endl;
40                 flag = true;
41                 break;
42             }
43             for(int i = 0; i < 4; i++){
44                 int nx = no.x+dirx[i], ny = no.y+diry[i];
45                 if((a[nx][ny]=='S'||a[nx][ny]=='.'||a[nx][ny]=='E')&&!visited[nx][ny][(step+1)%k] || a[nx][ny]=='#'&&!visited[nx][ny][(step+1)%k] && (step+1)%k==0){
46                     q.push(node(nx,ny,step+1));
47                     visited[nx][ny][(step+1)%k] = true;
48                 }
49             }
50         }
51         if(flag==false)cout<<"Oop!"<<endl;
52     }
53     return 0;
54 } 

备注:又是挺坎坷的一道题!!这道题就是显然BFS,巧妙方法是设置一个三维的visited数组,因为涉及到#的变化,这道题里走过的格子还是可以再走的,但什么时候没必要再次走进同样的格子呢?对于一个格子,如果踏入它的时间t,%k的结果是相同的,可以视作同样的状态。

然而WA数次甚至还有RE,都出了什么错呢?

我第一次WA是忽略了多组数据,找到解之后直接return 0了。然后是RE,原因又是老问题,我这次虽然记得S,.,E三种格子都可以走了,但我偷懒把标黄的条件写成了!=‘#’,这就不行了啊,因为数组里还有空格子,值为0,也满足这个条件,所以自然会让数组下标越界。那就分开写呗,然后我又WA了,因为这次记得加上S却忘了E。 所以,BFS在拓展节点的时候,什么能走什么不能走一定要想清楚!!!!

 

posted @ 2020-06-17 11:05  timeaftertime  阅读(755)  评论(0编辑  收藏  举报