Tuesday, August 4, 2020

UVa : 532 :: Dungeon Master

Problem : Please find the problem here.
Summary : The only thing special about this problem is that we have given a 3D grid, instead of more common 2D grids, and we need to find the shortest distance between two vertices. In 2D grid problem we check for four directions- North, East, South, West. In 3D grids we just need to take care of two more directions- Up and Down.
I would suggest to first solve this 2D grid problem before attempting this one.
Code : Since we want the shortest distance, we will use BFS.
#include <bits/stdc++.h>
using namespace std;

const int mxN = 30, di[6]={1, -1, 0, 0, 0, 0}, dj[6]={0, 0, 1, -1, 0, 0}, dk[6]={0, 0, 0, 0, 1, -1};
int l, n, m, si, sj, sk, ti, tj, tk, d[mxN][mxN][mxN];
string s[mxN][mxN];
bool vis[mxN][mxN][mxN];

bool isok(int i, int j, int k){
    return i>=0&&i<l&&j>=0&&j<n&&k>=0&&k<m&&s[i][j][k]=='.';
}

void solve(){
    for(int i = 0; i < l; i++){
        for(int j = 0; j < n; j++){
            cin >> s[i][j];
            for(int k = 0; k < m; k++){
                if(s[i][j][k] == 'S'){
                    si = i, sj = j, sk = k;
                }
                if(s[i][j][k] == 'E'){
                    ti = i, tj = j, tk = k, s[i][j][k] = '.';
                }
            }  
        }
        /*for(int j = 0; j < n; j++){
             for(int k = 0; k < m; k++){
                 cout << s[i][j][k];
             }
             cout << '\n';
          }
          cout << "\n\n";
        */
    }
    memset(vis, 0, sizeof(vis));
    memset(d, 0x3f, sizeof(d));
    queue<array<int, 3>> qu;
    qu.push({si, sj, sk});
    vis[si][sj][sk] = 1;
    d[si][sj][sk] = 0;
    while(qu.size()){
        array<int,3> u = qu.front();
        qu.pop();
        for(int k = 0; k < 6; k++){
            int ni = di[k]+u[0], nj = dj[k]+u[1], nk = dk[k]+u[2];
            if(isok(ni, nj, nk)){
                qu.push({ni, nj, nk});
                s[ni][nj][nk] = '#';
                vis[ni][nj][nk] = 1;
                if(d[ni][nj][nk] > d[u[0]][u[1]][u[2]]+1)
                    d[ni][nj][nk] = d[u[0]][u[1]][u[2]] + 1;
                }
            }
        }
        /*
        for(int i = 0; i < l; i++){
            for(int j = 0; j < n; j++){
                for(int k = 0; k < m; k++){
                    cout << vis[i][j][k];
                }
                cout << '\n';
            }
            cout << "\n\n";
        }*/
        if(vis[ti][tj][tk]){
            printf("Escaped in %d minute(s).\n",d[ti][tj][tk]);
        }else{
            cout << "Trapped!" << '\n';
        }
   }
}

int main()
{
    while(scanf("%d %d %d", &l, &n, &m) && (n&&l&&m)){
        solve();
    }
    return 0;
}

1 comment: