zoukankan      html  css  js  c++  java
  • lintcode598- Zombie in Matrix- medium

    Given a 2D grid, each cell is either a wall 2, a zombie 1or people 0 (the number zero, one, two).Zombies can turn the nearest people(up/down/left/right) into zombies every day, but can not through wall. How long will it take to turn all people into zombies? Return -1 if can not turn all people into zombies.

    Example

    Given a matrix:

    0 1 2 0 0
    1 0 0 2 1
    0 1 0 0 0
    

    return 2

     

    1. BFS。queue+size层级遍历。第一层是初始的僵尸。每天晚上推入僵尸旁边的新僵尸(注意处理过的僵尸不用再次处理了,因为不会再有影响,靠周围那圈才是新生力量)。遍历的同时用一个count记录剩余人类。人减到0终止遍历,或者queue空了终止遍历(僵尸不够格)。

    2.for循环。子函数每天做僵尸的咬人转换。主函数每天找到所有僵尸都做一次transfer。这个比较简单,但会有重复僵尸,效率不如前面的高。

    细节:1.变量定义,最前面最好写下int ZOMBIE = 1; 这种,更直观。2.这种矩阵的都小心索引边界确认+dxdy简洁写法。3.二维数组调用还是统一下吧,函数头写int x, int y,矩阵调用也用int[x][y],x和h比,y和w比。相当于把x看成向下指的坐标轴,y看成向右指的坐标轴,这样也自洽的。4. dxdy写法规范直接int[] dx = {-1, 0, 1, 0}; 等号右边不用写int说明

    1.BFS:

    public class Solution {
        /*
         * @param grid: a 2D integer grid
         * @return: an integer
         */
        
        private class Point {
            int x;
            int y;
            public Point(int x, int y) {
                this.x = x;
                this.y = y;
            }
        }
        
        public int zombie(int[][] grid) {
            // write your code here
            if (grid == null || grid.length == 0 || grid[0].length == 0) {
                return -1;
            }
            int h = grid.length;
            int w = grid[0].length;
            int HUMAN = 0;
            int ZOMBIE = 1;
            int WALL = 2;
            int[] dx = {-1, 0, 1, 0};
            int[] dy = {0, -1, 0, 1};
            
            int humanCnt = 0;
            int dayCnt = 0;
            Queue<Point> queue = new LinkedList<Point>();
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    if (grid[i][j] == HUMAN) {
                        humanCnt++;
                    } else if (grid[i][j] == ZOMBIE) {
                        queue.offer(new Point(i,j));
                    }
                }
            }
            
            if (humanCnt == 0) {
                return 0;
            }
            
            while (!queue.isEmpty()) {
                dayCnt++;
                // 你一开始忘了层级遍历!!!傻了把,那你就是每一个僵尸咬一次就加一天了
                int size = queue.size();
                for(int c = 0; c < size; c++) {
                    Point crt = queue.poll();
                    for (int i = 0; i < 4; i++) {
                        int cx = crt.x + dx[i];
                        int cy = crt.y + dy[i];
                        if (isValid(grid, cx, cy) && grid[cx][cy] == HUMAN) {
                            grid[cx][cy] = ZOMBIE;
                            queue.offer(new Point(cx,cy));
                            humanCnt--;
                            if (humanCnt == 0) {
                                return dayCnt;
                        }
                    }
                }
                }
                
            }
            
            return -1;
        }
        
        private boolean isValid(int[][] grid, int x, int y) {
            int h = grid.length;
            int w = grid[0].length;
            return x >= 0 && x < h && y >= 0 && y < w;
        }
    }

    2.for循环

    public class Solution {
        /*
         * @param grid: a 2D integer grid
         * @return: an integer
         */
        public int zombie(int[][] grid) {
            // write your code here
            if (grid == null || grid.length == 0 || grid[0].length == 0) {
                return -1;
            }
            
            int h = grid.length;
            int w = grid[0].length;
            boolean hasChange = true;
            int dayCount =0;
            
            while (hasChange) {
                dayCount++;
                hasChange = false;
                for (int i = 0; i < h; i++) {
                    for(int j = 0; j < w; j++) {
                        if (grid[i][j] == 1 && transfer(grid, i, j)) {
                            hasChange = true;
                        }
                    }
                }
                for (int i = 0; i < h; i++) {
                    for (int j = 0; j < w; j++) {
                        if (grid[i][j] == 3) {
                            grid[i][j] = 1;
                        }
                    }
                }
            }
            
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    if (grid[i][j] == 0) {
                        return -1;
                    }
                }
            }
            return dayCount - 1;
        }
        
        private boolean transfer(int[][] grid, int x, int y) {
            
            int[] dx = {-1, 0, 1, 0};
            int[] dy = {0, -1, 0, 1};
            boolean hasChange = false;
            
            for (int i = 0; i < 4; i++) {
                int cx = x + dx[i];
                int cy = y + dy[i];
                if (isValid(grid, cx, cy) && grid[cx][cy] == 0) {
                    grid[cx][cy] = 3;
                    hasChange = true;
                }
            }
            return hasChange;
        }
        
        private boolean isValid(int[][] grid, int x, int y) {
            int h = grid.length;
            int w = grid[0].length;
            
            return x >= 0 && x < h && y >= 0 && y < w;
        }
    }
  • 相关阅读:
    HDU4507 吉哥系列故事――恨7不成妻(数位dp)
    UCF Local Programming Contest 2017 G题(dp)
    ICPC Latin American Regional Contests 2019 I题
    UCF Local Programming Contest 2017 H题(区间dp)
    HDU2089 不要62
    AcWing1084 数字游戏II(数位dp)
    UCF Local Programming Contest 2017 F题(最短路)
    Google Code Jam 2019 Round 1A Pylons(爆搜+贪心)
    AcWing1083 Windy数(数位dp)
    Vue
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7745905.html
Copyright © 2011-2022 走看看