Grid Illumination

On a N x N grid of cells, each cell (x, y) with 0 <= x < N and 0 <= y < N has a lamp.

Initially, some number of lamps are on.  lamps[i] tells us the location of the i-th lamp that is on.  Each lamp that is on illuminates every square on its x-axis, y-axis, and both diagonals (similar to a Queen in chess).

For the i-th query queries[i] = (x, y), the answer to the query is 1 if the cell (x, y) is illuminated, else 0.

After each query (x, y) [in the order given by queries], we turn off any lamps that are at cell (x, y) or are adjacent 8-directionally (ie., share a corner or edge with cell (x, y).)

Return an array of answers.  Each value answer[i] should be equal to the answer of the i-th query queries[i].

Example 1:

Input: N = 5, lamps = [[0,0],[4,4]], queries = [[1,1],[1,0]]
Output: [1,0]
Explanation: 
Before performing the first query we have both lamps [0,0] and [4,4] on.
The grid representing which cells are lit looks like this, where [0,0] is the top left corner, and [4,4] is the bottom right corner:
1 1 1 1 1
1 1 0 0 1
1 0 1 0 1
1 0 0 1 1
1 1 1 1 1
Then the query at [1, 1] returns 1 because the cell is lit.  After this query, the lamp at [0, 0] turns off, and the grid now looks like this:
1 0 0 0 1
0 1 0 0 1
0 0 1 0 1
0 0 0 1 1
1 1 1 1 1
Before performing the second query we have only the lamp [4,4] on.  Now the query at [1,0] returns 0, because the cell is no longer lit.

Note:

  1. 1 <= N <= 10^9
  2. 0 <= lamps.length <= 20000
  3. 0 <= queries.length <= 20000
  4. lamps[i].length == queries[i].length == 2

题目理解:

给定一个二维数组表示的地图,地图中的某一些位置亮着灯,灯可以照亮它所在的行、列和两个对角线上全部的位置。给定一系列位置,查询给定位置是否被照亮。

在某一个位置被查询之后,这个位置和这个位置周围8个位置的灯全部被熄灭(如果亮着的话)

解题思路:

将每一个亮着的灯都映射到区域的边界上。因为亮灯位置的行、列、对角线都会被照亮,因此记录所有亮灯位置的行、列,在处理对角线时,可以存储它所在的对角线与地图边界相交的位置,也就是存储这个对角线上行坐标最小的位置(也可以存储其他的位置,只要易于表示就行)。

在查询pos位置的时候,如果pos所在的行,或者列,或者两个对角线最上面的坐标有记录,那么它就被照亮了。

在查询完成之后,需要关闭周围9个位置的灯。同样的方法反过来用,将对应位置映射的行、列、对角线删除就可以。

因为有的行、列、对角线会被多个灯照亮,熄灭其中一个之后,仍然处于被照亮的状态。因此我们要记录每一行被照亮的次数,熄灭等的时候将次数减一。

class Solution {
    int N;
    int[][] dirs = new int[][]{{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1},{0,0}};

    public long[] getDiagonals(int[] lamp){
        long i = lamp[0], j = lamp[1];
        long left, right;
        if(i > j){
            left = (i - j) * N;
        }
        else{
            left = j - i;
        }
        if(j + i < N){
            right = j + i;
        }
        else{
            right = (i - (N - j - 1)) * N + N - 1;
        }
        return new long[]{left, right};
    }

    public int[] gridIllumination(int N, int[][] lamps, int[][] queries) {
        Map<Integer, Integer> left = new HashMap<>(), top = new HashMap<>();
        Map<Long, Integer> leftTop = new HashMap<>(), rightTop = new HashMap<>();
        Set<Long> set = new HashSet<>();
        this.N = N;
        for(int[] lamp : lamps){
            set.add((long) (lamp[0] * N + lamp[1]));
            left.put(lamp[0], left.getOrDefault(lamp[0], 0) + 1);
            top.put(lamp[1], top.getOrDefault(lamp[1], 0) + 1);
            long[] diagonals = getDiagonals(lamp);
            leftTop.put(diagonals[0], leftTop.getOrDefault(diagonals[0], 0) + 1);
            rightTop.put(diagonals[1], rightTop.getOrDefault(diagonals[1], 0) + 1);
        }
        int len = queries.length;
        int[] res = new int[len];
        for(int i = 0; i < len; i++){
            int[] query = queries[i];
            int x = query[0], y = query[1];
            if(left.containsKey(x) && left.get(x) > 0)
                res[i] = 1;
            if(top.containsKey(y) && top.get(y) > 0)
                res[i] = 1;
            long[] diagonals = getDiagonals(query);
            if(leftTop.containsKey(diagonals[0]) && leftTop.get(diagonals[0]) > 0)
                res[i] = 1;
            if(rightTop.containsKey(diagonals[1]) && rightTop.get(diagonals[1]) > 0)
                res[i] = 1;
            for(int[] dir : dirs){
                int nx = x + dir[0], ny = y + dir[1];
                long pos = (long)nx * N + ny;
                if(nx > -1 && nx < N && ny > -1 && ny < N && set.contains(pos)){
                    left.put(nx, left.get(nx) - 1);
                    top.put(ny, top.get(ny) - 1);
                    long[] temp = getDiagonals(new int[]{nx, ny});
                    leftTop.put(temp[0], leftTop.get(temp[0]) - 1);
                    rightTop.put(temp[1], rightTop.get(temp[1]) - 1);
                    set.remove(pos);
                }
            }
        }
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/m0_37889928/article/details/88223121
今日推荐