Lizou punch card 2021.1.16 punch brick

Problem:
There is a binary grid of mxn, where 1 means brick and 0 means blank. The premise that the bricks are stable (will not fall) are:

When a brick is directly connected to the top of the grid, or
at least one adjacent brick (one of the 4 directions) is stable and will not fall,
you will be given an array of hits, which is where the bricks need to be eliminated in turn. Whenever the brick at the position of hits[i] = (rowi, coli) is eliminated, the brick at the corresponding position (if any) will disappear, and then other bricks may fall due to this elimination operation. Once a brick falls, it will immediately disappear from the grid (ie, it will not fall on other stable bricks).

Return an array result, where result[i] represents the number of bricks dropped corresponding to the i-th elimination operation.

Note that the elimination may point to a blank position without bricks. If this happens, no bricks will fall.

Example 1:

Input: grid = [[1,0,0,0],[1,1,1,0]], hits = [[1,0]]
Output: [2]
Explanation: The
grid starts as:
[[1 ,0,0,0],
[1,1,1,0]]
eliminate the thickened bricks at (1,0) to get the grid:
[[1,0,0,0]
[0,1, 1,0]] The
two bold bricks are no longer stable because they are no longer connected to the top and no longer adjacent to another stable brick, so they will fall. Get the grid:
[[1,0,0,0],
[0,0,0,0]]
Therefore, the result is [2].
Example 2:

Input: grid = [[1,0,0,0],[1,1,0,0]], hits = [[1,1],[1,0]]
Output: [0,0]
Explanation:
The grid starts as:
[[1,0,0,0],
[1,1,0,0]]
Eliminate the thickened bricks at (1,1) to get the grid:
[[1,0,0 ,0],
[1,0,0,0]] The
remaining bricks are very stable, so they will not fall. The grid remains unchanged:
[[1,0,0,0],
[1,0,0,0]]
Next, eliminate the thick bricks at (1,0) to get the grid:
[[1, 0,0,0],
[0,0,0,0]] The
remaining bricks are still stable, so no bricks will fall.
Therefore, the result is [0,0].

Code (reverse order + union search set):

class UnionFind {
    
    
private:
    vector<int> f, sz;
public:
    UnionFind(int n): f(n), sz(n) {
    
    
        for (int i = 0; i < n; i++) {
    
    
            f[i] = i;
            sz[i] = 1;
        }
    }

    int find(int x) {
    
    
        if (f[x] == x) {
    
    
            return x;
        }
        int newf = find(f[x]);
        f[x] = newf;
        return f[x];
    }

    void merge(int x, int y) {
    
    
        int fx = find(x), fy = find(y);
        if (fx == fy) {
    
    
            return;
        }
        f[fx] = fy;
        sz[fy] += sz[fx];
    }

    int size(int x) {
    
    
        return sz[find(x)];
    }
};

class Solution {
    
    
public:
    vector<int> hitBricks(vector<vector<int>>& grid, vector<vector<int>>& hits) {
    
    
        int h = grid.size(), w = grid[0].size();
        
        UnionFind uf(h * w + 1);
        vector<vector<int>> status = grid;
        for (int i = 0; i < hits.size(); i++) {
    
    
            status[hits[i][0]][hits[i][1]] = 0;
        }
        for (int i = 0; i < h; i++) {
    
    
            for (int j = 0; j < w; j++) {
    
    
                if (status[i][j] == 1) {
    
    
                    if (i == 0) {
    
    
                        uf.merge(h * w, i * w + j);
                    }
                    if (i > 0 && status[i - 1][j] == 1) {
    
    
                        uf.merge(i * w + j, (i - 1) * w + j);
                    }
                    if (j > 0 && status[i][j - 1] == 1) {
    
    
                        uf.merge(i * w + j, i * w + j - 1);
                    }
                }
            }
        }
        const vector<pair<int, int>> directions{
    
    {
    
    0, 1},{
    
    1, 0},{
    
    0, -1},{
    
    -1, 0}};
        vector<int> ret(hits.size(), 0);
        for (int i = hits.size() - 1; i >= 0; i--) {
    
    
            int r = hits[i][0], c = hits[i][1];
            if (grid[r][c] == 0) {
    
    
                continue;
            }
            int prev = uf.size(h * w);

            if (r == 0) {
    
    
                uf.merge(c, h * w);
            }
            for (const auto [dr, dc]: directions) {
    
    
                int nr = r + dr, nc = c + dc;
                
                if (nr >= 0 && nr < h && nc >= 0 && nc < w) {
    
    
                    if (status[nr][nc] == 1) {
    
    
                        uf.merge(r * w + c, nr * w + nc);
                    }
                }
            }
            int size = uf.size(h * w);
            ret[i] = max(0, size - prev - 1);
            status[r][c] = 1;
        }
        return ret;
    }
};

Guess you like

Origin blog.csdn.net/weixin_45780132/article/details/112691455