• 864. Shortest Path to Get All Keys


    We are given a 2-dimensional grid"." is an empty cell, "#" is a wall, "@" is the starting point, ("a""b", ...) are keys, and ("A""B", ...) are locks.

    We start at the starting point, and one move consists of walking one space in one of the 4 cardinal directions.  We cannot walk outside the grid, or walk into a wall.  If we walk over a key, we pick it up.  We can't walk over a lock unless we have the corresponding key.

    For some 1 <= K <= 6, there is exactly one lowercase and one uppercase letter of the first K letters of the English alphabet in the grid.  This means that there is exactly one key for each lock, and one lock for each key; and also that the letters used to represent the keys and locks were chosen in the same order as the English alphabet.

    Return the lowest number of moves to acquire all keys.  If it's impossible, return -1.

    Example 1:

    Input: ["@.a.#","###.#","b.A.B"]
    Output: 8
    

    Example 2:

    Input: ["@..aA","..B#.","....b"]
    Output: 6
    

    Note:

    1. 1 <= grid.length <= 30
    2. 1 <= grid[0].length <= 30
    3. grid[i][j] contains only '.''#''@''a'-'f' and 'A'-'F'
    4. The number of keys is in [1, 6].  Each key has a different letter and opens exactly one lock.

    Approach #1: C++. [BFS]

    class Solution {
    public:
        int shortestPathAllKeys(vector<string>& grid) {
            int m = grid.size();
            int n = grid[0].size();
            queue<int> q;
            vector<vector<vector<int>>> seen(m, vector<vector<int>>(n, vector<int>(64, 0)));
            int allKeys = 0;
            
            //Init
            for (int i = 0; i < m; ++i) {
                for (int j = 0; j < n; ++j) {
                    const char c = grid[i][j];
                    if (c == '@') {
                        q.push((i << 16) | (j << 8));
                        seen[i][j][0] = 1;
                    } else if (c >= 'a' && c <= 'f') {
                        allKeys |= (1 << (c - 'a')); 
                    }
                }
            }
            
            int steps = 0;
            vector<int> dirs = {-1, 0, 1, 0, -1};
            
            while (!q.empty()) {
                int size = q.size();
                while (size--) {
                    int cur = q.front(); q.pop();
                    int x = cur >> 16;
                    int y = (cur >> 8) & 0xFF;
                    int keys = cur & 0xFF;
                    
                    if (keys == allKeys) return steps;
                    
                    for (int i = 0; i < 4; ++i) {
                        int xx = x + dirs[i];
                        int yy = y + dirs[i+1];
                        int curKeys = keys;
                        if (xx < 0 || xx >= m || yy < 0 || yy >= n) continue;
                        const char c = grid[xx][yy];
                        if (c == '#') continue;
                        if (c >= 'A' && c <= 'F' && !(keys & (1 << (c - 'A')))) continue;
                        if (c >= 'a' && c <= 'f') curKeys |= 1 << (c - 'a');
                        if (seen[xx][yy][curKeys]) continue;
                        seen[xx][yy][curKeys] = 1;
                        q.push((xx << 16) | (yy << 8) | curKeys);
                    }
                }
                steps++;
            }
            
            return -1;
        }
    };
    

      

    Analysis:

    seen[x][y][keys] : To store the position and the number of keys. If this state don't be traveled we can do next step, otherwise we skip this state.

    allKeys : To represent the keys which we will collect in this problem. In this problem we use six binary numbers to represent all the keys at difference bit. 

    such as : a -> 1 so it will be represented by 000001 and f -> f - 'a' = 6 so it will be represent by 100000. If we have the keys of a and f so we can use 100001 to represent that.

    queue<int> q : To simulation the BFS.

    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    集合类List,set,Map 的遍历方法,用法和区别
    如何优化sql语句
    io流(详询请加qq:2085920154)
    Servlet过滤器(详询请加qq:2085920154)
    oracle,sqlserver同一个表两个字段和成一个列查询 (详询请加qq:2085920154)
    SQL SERVER 将表中字符串转换为数字的函数 (详询请加qq:2085920154)
    SQL SERVER增加、删除、更改表中的字段名 (详询请加qq:2085920154)
    SQL Server日期时间格式转换字符串详解 (详询请加qq:2085920154)
    把文件打成zip或然rar下载 (详询请加qq:2085920154)
    计算机网络-校招总结
  • 原文地址:https://www.cnblogs.com/h-hkai/p/10198042.html
Copyright © 2020-2023  润新知