Bricks Falling When Hit in C++


Suppose we have a grid of binary values (0s and 1s) the 1s in a cell represent the bricks. A brick will not drop when that satisfies these conditions −

  • Either brick is directly connected to the top of the grid

  • or at least one of its adjacent (top, bottom, left, right) bricks will not drop.

We will do some erasures sequentially. In each case we want to do the erasure at the location (i, j), the brick (if that is present) on that location will disappear, and then some other bricks may drop because of that erasure. We have to find the array representing the number of bricks that will drop after each erasure in sequence.

So, if the input is like grid = [[1,0,0,0],[1,1,1,0]] and hits = [[1,0]], then the output will be [2], this is because if we remove the brick placed at (1, 0), the brick at (1, 1) and (1, 2) will drop. So we should return 2.

To solve this, we will follow these steps −

  • Define an array dir of size: 4 x 2, dir := {{1, 0}, { - 1, 0}, {0, 1}, {0, - 1}}

  • Define a function dfs(), this will take i, j, the grid,

  • if when (i,j) are inside the grid region and grid[i, j] is not equal to 1, then−

    • return 0

  • ret := 1

  • grid[i, j] := 2

  • for initialize k := 0, when k < 4, update (increase k by 1), do −

    • ret := ret + dfs(i + dir[k, 0], j + dir[k, 1], grid)

  • return ret

  • Define a function notConnected(), this will take x, y, and grid,

  • for initialize k := 0, when k < 4, update (increase k by 1), do −

    • nx := x + dir[k, 0], ny := y + dir[k, 1]

    • if (nx, ny) is in the range of grid, then −

      • Ignore following part, skip to the next iteration

    • if grid[nx, ny] is same as 2, then −

      • return true

  • return true when x is same as 0

  • From the main method, do the following −

  • Define an array ret

  • for initialize i := 0, when i < size of hits, update (increase i by 1), do −

    • grid[hits[i, 0], hits[i, 1]] := grid[hits[i, 0], hits[i, 1]] - 1

  • for initialize i := 0, when i < size of grid, update (increase i by 1), do −

    • dfs(0, i, grid)

  • reverse the array hits

  • for initialize i := 0, when i < size of hits, update (increase i by 1), do −

    • x := hits[i, 0], y := hits[i, 1]

    • if grid[x, y] is same as 1 and notConnected(x, y, grid), then −

      • insert dfs(x, y, grid) at the end of ret

    • Otherwise

      • insert 0 at the end of ret

  • reverse the array ret

  • return ret

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
   cout << "[";
   for(int i = 0; i<v.size(); i++){
      cout << v[i] << ", ";
   }
   cout << "]"<<endl;
}
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
class Solution {
   public:
   int dfs(int i, int j, vector<vector<int> >& grid){
      if (i < 0 || j < 0 || i >= grid.size() || j >= grid[0].size() || grid[i][j] != 1) {
         return 0;
      }
      int ret = 1;
      grid[i][j] = 2;
      for (int k = 0; k < 4; k++) {
         ret += dfs(i + dir[k][0], j + dir[k][1], grid);
      }
      return ret;
   }
   bool notConnected(int x, int y, vector<vector<int> >& grid){
      for (int k = 0; k < 4; k++) {
         int nx = x + dir[k][0];
         int ny = y + dir[k][1];
         if (nx < 0 || ny < 0 || nx >= grid.size() || ny >= grid[0].size())
         continue;
         if (grid[nx][ny] == 2) {
            return true;
         }
      }
      return x == 0;
   }
   vector<int> hitBricks(vector<vector<int> >& grid, vector<vector<int> >& hits){
      vector<int> ret;
      for (int i = 0; i < hits.size(); i++) {
         grid[hits[i][0]][hits[i][1]] -= 1;
      }
      for (int i = 0; i < grid.size(); i++) {
         dfs(0, i, grid);
      }
      reverse(hits.begin(), hits.end());
      for (int i = 0; i < hits.size(); i++) {
         int x = hits[i][0];
         int y = hits[i][1];
         grid[x][y] += 1;
         if (grid[x][y] == 1 && notConnected(x, y, grid))
         ret.push_back(dfs(x, y, grid) - 1);
         else
         ret.push_back(0);
      }
      reverse(ret.begin(), ret.end());
      return ret;
   }
};
main(){
   Solution ob;
   vector<vector<int>> v = {{1,0,0,0},{1,1,1,0}};
   vector<vector<int>> v1 ={{1,0}};
   print_vector(ob.hitBricks(v, v1));
}

Input

{{1,0,0,0},{1,1,1,0}}, {{1,0}}

Output

[2, ]

Updated on: 08-Jun-2020

91 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements