列表

详情


LCP 56. 信物传送

欢迎各位勇者来到力扣城,本次试炼主题为「信物传送」。

本次试炼场地设有若干传送带,matrix[i][j] 表示第 ij 列的传送带运作方向,"^","v","<",">" 这四种符号分别表示 上、下、左、右 四个方向。信物会随传送带的方向移动。勇者每一次施法操作,可临时变更一处传送带的方向,在物品经过后传送带恢复原方向。 lcp (2).gif{:width=300px}

通关信物初始位于坐标 start处,勇者需要将其移动到坐标 end 处,请返回勇者施法操作的最少次数。

注意:

示例 1:

输入:matrix = [">>v","v^<","<><"], start = [0,1], end = [2,0]

输出:1

解释: 如上图所示 当信物移动到 [1,1] 时,勇者施法一次将 [1,1] 的传送方向 ^ 从变更为 < 从而信物移动到 [1,0],后续到达 end 位置 因此勇者最少需要施法操作 1 次

示例 2:

输入:matrix = [">>v",">>v","^<<"], start = [0,0], end = [1,1]

输出:0

解释:勇者无需施法,信物将自动传送至 end 位置

示例 3:

输入:matrix = [">^^>","<^v>","^v^<"], start = [0,0], end = [1,3]

输出:3

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int conveyorBelt(vector<string>& matrix, vector<int>& start, vector<int>& end) { } };

python3 解法, 执行用时: 84 ms, 内存消耗: 16.2 MB, 提交时间: 2023-10-25 10:33:33

d = {"^": (-1, 0),"v": (1, 0),"<": (0, -1),">": (0, 1)}
class Solution:
    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:
        m, n = len(matrix), len(matrix[0])
        q = deque([(0, start[0], start[1])])
        book = [[1234567890123] * n for _ in range(m)]
        book[start[0]][start[1]] = 0
        while q:
            t, x, y = q.popleft()
            if [x, y] == end: return t
            for dr, (dx, dy) in d.items():
                nx, ny = x + dx, y + dy
                if not (0 <= nx < m and 0 <= ny < n): continue
                nt = t + int(dr != matrix[x][y])
                if dr == matrix[x][y]:
                    if book[nx][ny] <= t: continue
                    book[nx][ny] = t
                    q.appendleft((t, nx, ny))
                else:
                    if book[nx][ny] <= t + 1: continue
                    book[nx][ny] = t + 1
                    q.append((t + 1, nx, ny))

java 解法, 执行用时: 15 ms, 内存消耗: 42.1 MB, 提交时间: 2023-10-25 10:31:26

class Solution {
    
    private int ans;
    private int[][] dis;
    private int[][] dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    public void spfa(int[] start, int[] end, int m, int n, char[][] map, int cnt){
        Queue<int[]> q = new LinkedList<>();
        q.offer(start);
        dis[start[0]][start[1]] = 0;
        while (!q.isEmpty()){
            int[] cur = q.poll();
            for (int i = 0; i < 4; ++i){
                int x = cur[0] + dir[i][0], y = cur[1] + dir[i][1];
                if (x >= 0 && x < m && y >= 0 && y < n){
                    int len = 1;
                    if ((i == 0 && map[cur[0]][cur[1]] == '^')
                            || (i == 1 && map[cur[0]][cur[1]] == 'v')
                            || (i == 2 && map[cur[0]][cur[1]] == '<')
                            || (i == 3 && map[cur[0]][cur[1]] == '>')){
                        len = 0;
                    }
                    if (dis[cur[0]][cur[1]] + len < dis[x][y]){
                        dis[x][y] = dis[cur[0]][cur[1]] + len;
                        q.offer(new int[]{x, y});
                    }
                }
            }
        }
    }

    public int conveyorBelt(String[] matrix, int[] start, int[] end) {
        int m = matrix.length, n = matrix[0].length();
        char[][] map = new char[m][n];
        for (int i = 0; i < m; ++i){
            map[i] = matrix[i].toCharArray();
        }
        dis = new int[m][n];
        for (int i = 0; i < m; ++i){
            for (int j = 0; j < n; ++j){
                dis[i][j] = 1000000;
            }
        }
        ans = Integer.MAX_VALUE;
        spfa(start, end, m, n, map, 0);
        return dis[end[0]][end[1]];
    }
}

cpp 解法, 执行用时: 8 ms, 内存消耗: 9.3 MB, 提交时间: 2023-10-25 10:30:53

class Solution {
public:
    typedef pair<int, int> PII;
    int dist[110][110]; //需要更改传送带的次数。
    bool st[110][110];
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; //4个方向。上右下左。
    char g[4] = {'^', '>', 'v', '<'};
    
    int conveyorBelt(vector<string>& matrix, vector<int>& start, vector<int>& end) {
        int n = matrix.size(), m = matrix[0].size();
        
        deque<PII> q;
        
        q.push_back({start[0], start[1]});
        memset(dist, -1, sizeof dist);
        dist[start[0]][start[1]] = 0;
        
        while (q.size())
        {
            auto t = q.front();
            q.pop_front();
            
            int x = t.first, y = t.second;
            //到终点,直接return
            if (x == end[0]  && y == end[1]) return dist[x][y];
            if (st[x][y]) continue;
            st[x][y] = true;
            
            //printf("x = %d, y = %d, dist = %d\n", x, y, dist[x][y]);
            for (int i = 0; i < 4; i ++ )
            {
                int a = x + dx[i], b = y + dy[i];
                if (a < 0 || a >= n || b < 0 || b >= m || st[a][b]) continue;
                
                if (g[i] == matrix[x][y]) //如果当前前进的方向 和传送带一个方向 加入队头
                {
                    q.push_front({a, b});
                    dist[a][b] = dist[x][y];
                }
                else //前进方向和传送带不是一个方向,加入队尾。
                {
                    q.push_back({a, b});
                    //如果当前点被更新过, 则更新为最小值。
                    if (dist[a][b] != -1) dist[a][b] = min(dist[a][b], dist[x][y] + 1);
                    else dist[a][b] = dist[x][y] + 1;
                }
                //cout << a << ' ' << b << ' ' << dist[a][b] << endl;
            }
        }
        return 0;
    }
};

上一题