Bootstrap

【2024华为OD-E卷-200分-跳格子2】(题目+思路+Java&C++&Python解析)

题目描述

在一个二维平面上,有一个 n x m 的网格,每个格子有一个非负整数。你从左上角 (0, 0) 开始,每次只能向右或向下移动,目标是到达右下角 (n-1, m-1)。

在移动过程中,你需要记录经过的格子中,最大数字与最小数字的差的最小值。

输入

  • 第一行包含两个整数 n 和 m,表示网格的行数和列数。
  • 接下来的 n 行,每行包含 m 个整数,表示网格中每个格子的值。

输出

  • 输出一个整数,表示从左上角到右下角路径中,最大数字与最小数字的差的最小值。

限制条件

  • 1 <= n, m <= 500
  • 0 <= grid[i][j] <= 10^9

思路分析

这个问题可以转化为求从左上角到右下角路径中的最大值和最小值,并计算它们的差值。我们可以使用动态规划(Dynamic Programming, DP)来求解这个问题。

  1. 定义状态
    • maxDP[i][j] 表示从 (0, 0) 到 (i, j) 路径中的最大值。
    • minDP[i][j] 表示从 (0, 0) 到 (i, j) 路径中的最小值。
  2. 状态转移
    • maxDP[i][j] = max(maxDP[i-1][j], maxDP[i][j-1], grid[i][j])
    • minDP[i][j] = min(minDP[i-1][j], minDP[i][j-1], grid[i][j])
  3. 初始化
    • maxDP[0][0] = grid[0][0]
    • minDP[0][0] = grid[0][0]
  4. 计算最终结果
    • 遍历整个 maxDP 和 minDP 数组,计算 maxDP[i][j] - minDP[i][j] 的最小值。

Java 代码解析

public class JumpGrid {
    public static int minDifference(int[][] grid) {
        int n = grid.length;
        int m = grid[0].length;
        
        int[][] maxDP = new int[n][m];
        int[][] minDP = new int[n][m];
        
        maxDP[0][0] = grid[0][0];
        minDP[0][0] = grid[0][0];
        
        for (int i = 1; i < n; i++) {
            maxDP[i][0] = Math.max(maxDP[i-1][0], grid[i][0]);
            minDP[i][0] = Math.min(minDP[i-1][0], grid[i][0]);
        }
        
        for (int j = 1; j < m; j++) {
            maxDP[0][j] = Math.max(maxDP[0][j-1], grid[0][j]);
            minDP[0][j] = Math.min(minDP[0][j-1], grid[0][j]);
        }
        
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < m; j++) {
                maxDP[i][j] = Math.max(maxDP[i-1][j], Math.max(maxDP[i][j-1], grid[i][j]));
                minDP[i][j] = Math.min(minDP[i-1][j], Math.min(minDP[i][j-1], grid[i][j]));
            }
        }
        
        int minDiff = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                minDiff = Math.min(minDiff, maxDP[i][j] - minDP[i][j]);
            }
        }
        
        return minDiff;
    }
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int[][] grid = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                grid[i][j] = scanner.nextInt();
            }
        }
        System.out.println(minDifference(grid));
    }
}

C++ 代码解析

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>

using namespace std;

int minDifference(vector<vector<int>>& grid) {
    int n = grid.size();
    int m = grid[0].size();
    
    vector<vector<int>> maxDP(n, vector<int>(m));
    vector<vector<int>> minDP(n, vector<int>(m));
    
    maxDP[0][0] = grid[0][0];
    minDP[0][0] = grid[0][0];
    
    for (int i = 1; i < n; i++) {
        maxDP[i][0] = max(maxDP[i-1][0], grid[i][0]);
        minDP[i][0] = min(minDP[i-1][0], grid[i][0]);
    }
    
    for (int j = 1; j < m; j++) {
        maxDP[0][j] = max(maxDP[0][j-1], grid[0][j]);
        minDP[0][j] = min(minDP[0][j-1], grid[0][j]);
    }
    
    for (int i = 1; i < n; i++) {
        for (int j = 1; j < m; j++) {
            maxDP[i][j] = max({maxDP[i-1][j], maxDP[i][j-1], grid[i][j]});
            minDP[i][j] = min({minDP[i-1][j], minDP[i][j-1], grid[i][j]});
        }
    }
    
    int minDiff = INT_MAX;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            minDiff = min(minDiff, maxDP[i][j] - minDP[i][j]);
        }
    }
    
    return minDiff;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> grid[i][j];
        }
    }
    cout << minDifference(grid) << endl;
    return 0;
}

Python 代码解析

def min_difference(grid):
    n = len(grid)
    m = len(grid[0])
    
    max_dp = [[0] * m for _ in range(n)]
    min_dp = [[0] * m for _ in range(n)]
    
    max_dp[0][0] = grid[0][0]
    min_dp[0][0] = grid[0][0]
    
    for i in range(1, n):
        max_dp[i][0] = max(max_dp[i-1][0], grid[i][0])
        min_dp[i][0] = min(min_dp[i-1][0], grid[i][0])
    
    for j in range(1, m):
        max_dp[0][j] = max(max_dp[0][j-1], grid[0][j])
        min_dp[0][j] = min(min_dp[0][j-1], grid[0][j])
    
    for i in range(1, n):
        for j in range(1, m):
            max_dp[i][j] = max(max_dp[i-1][j], max_dp[i][j-1], grid[i][j])

 

;