• 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在拓展节点的时候,什么能走什么不能走一定要想清楚!!!!

  • 相关阅读:
    工厂方法模式
    策略模式
    MySQL
    装饰模式
    里式代换原则
    依赖倒转原则
    Java 7 for Absolute Beginners/Java 7基础教程--读后感
    Java 7 for Absolute Beginners/Java 7基础教程--代码纠错
    Eclipse JVM terminated.exit code=13
    Java程序设计教程(第2版)阅读总结
  • 原文地址:https://www.cnblogs.com/fangziyuan/p/13151274.html
Copyright © 2020-2023  润新知