2020 Jan Platinum Problem 3 Falling Portals

From Wiki
Jump to navigation Jump to search

Official Problem Statement[edit]

Falling Portals

Problem Statement:

Given a rectangular grid of size N by M, each cell in the grid contains either a portal or a wall. A portal is a cell that can be used to teleport from one cell to another. A wall is an impassable cell.

The goal is to find the minimum number of moves required to reach the bottom right corner of the grid from the top left corner.

Solution:

The solution to this problem is to use a Breadth-First Search (BFS) algorithm. We start by creating a queue of cells to visit and add the top left cell to it. Then, we loop through the queue and for each cell, we check if it is a portal. If it is, we add the cell it teleports to to the queue. If it is not a portal, we check if it is the bottom right cell. If it is, we return the number of moves required to reach it. Otherwise, we add all of its adjacent cells to the queue. We repeat this process until we find the bottom right cell or the queue is empty.

Code Example (C++):

  1. include <iostream>
  2. include <queue>
  3. include <vector>

using namespace std;

const int MAXN = 100; const int MAXM = 100;

int N, M; int grid[MAXN][MAXM]; int dist[MAXN][MAXM];

struct Cell {

   int x, y;

};

int bfs() {

   queue<Cell> q;
   Cell start = {0, 0};
   q.push(start);
   dist[0][0] = 0;
   while (!q.empty()) {
       Cell curr = q.front();
       q.pop();
       if (curr.x == N - 1 && curr.y == M - 1) {
           return dist[curr.x][curr.y];
       }
       if (grid[curr.x][curr.y] == 1) {
           Cell next = {curr.x + 1, curr.y};
           if (next.x < N && dist[next.x][next.y] == -1) {
               dist[next.x][next.y] = dist[curr.x][curr.y] + 1;
               q.push(next);
           }
           next = {curr.x, curr.y + 1};
           if (next.y < M && dist[next.x][next.y] == -1) {
               dist[next.x][next.y] = dist[curr.x][curr.y] + 1;
               q.push(next);
           }
       } else {
           Cell next = {grid[curr.x][curr.y], curr.y};
           if (next.x < N && dist[next.x][next.y] == -1) {
               dist[next.x][next.y] = dist[curr.x][curr.y] + 1;
               q.push(next);
           }
           next = {curr.x, grid[curr.x][curr.y]};
           if (next.y < M && dist[next.x][next.y] == -1) {
               dist[next.x][next.y] = dist[curr.x][curr.y] + 1;
               q.push(next);
           }
       }
   }
   return -1;

}

int main() {

   cin >> N >> M;
   for (int i = 0; i < N; i++) {
       for (int j = 0; j < M; j++) {
           cin >> grid[i][j];
           dist[i][j] = -1;
       }
   }
   cout << bfs() << endl;
   return 0;

}