豆包MarsCode AI 刷题
小M的蛋糕切割问题
问题描述
小M有一个 n×mn×m 的矩形蛋糕,蛋糕被分为 n×mn×m 个区域,每个区域都有一个美味度。她希望通过一刀将蛋糕切成两部分,一部分自己吃,另一部分给小团。切下的区域必须是完整的,即不能把某个小正方形切成两个小区域。
小M希望两个人吃的部分的美味度之和尽量接近。你的任务是计算出美味度差的最小值,即 ∣s1−s2∣∣s1−s2∣ 的最小值,其中 s1s1 是小M吃到的美味度,s2s2 是小团吃到的美味度。
问题理解
我们需要将一个 n×m 的矩形蛋糕切成两部分,使得两部分的美味度之和尽量接近。切割必须是完整的,即不能把某个小正方形切成两个小区域。我们的目标是找到一种切割方式,使得两部分的美味度之和的差值最小。
数据结构选择
由于我们处理的是一个二维数组,我们可以直接使用二维数组来存储蛋糕的美味度。
算法步骤
- 计算总和:首先计算整个蛋糕的美味度总和 totalSum。
- 水平切割:遍历所有可能的水平切割线(从第1行到第n-1行),计算切割线上方的部分的美味度总和 sum1,然后用 totalSum - sum1 计算下方的部分的美味度总和 sum2,并计算差值 diff,更新最小差值 minDiff。
- 垂直切割:遍历所有可能的垂直切割线(从第1列到第m-1列),计算切割线左侧的部分的美味度总和 sum1,然后用 totalSum - sum1 计算右侧的部分的美味度总和 sum2,并计算差值 diff,更新最小差值 minDiff。
- 返回结果:最终返回最小差值 minDiff。
详细步骤
- 计算总和:
-
- 遍历整个二维数组,累加所有元素的值,得到 totalSum。
- 水平切割:
-
- 对于每一行 i(从1到n-1),计算切割线上方的部分的美味度总和 sum1。
- 计算切割线下方的部分的美味度总和 sum2,即 totalSum - sum1。
- 计算差值 diff,即 |sum1 - sum2|。
- 更新最小差值 minDiff。
- 垂直切割:
-
- 对于每一列 j(从1到m-1),计算切割线左侧的部分的美味度总和 sum1。
- 计算切割线右侧的部分的美味度总和 sum2,即 totalSum - sum1。
- 计算差值 diff,即 |sum1 - sum2|。
- 更新最小差值 minDiff。
- 返回结果:
-
- 返回 minDiff,即美味度差的最小值。
// 计算整个蛋糕的美味度总和 int totalSum = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { totalSum += a[i][j]; } } int minDiff = Integer.MAX_VALUE; // 尝试所有水平切割线 for (int i = 1; i < n; i++) { int sum1 = 0; for (int row = 0; row < i; row++) { for (int col = 0; col < m; col++) { sum1 += a[row][col]; } } int sum2 = totalSum - sum1; int diff = Math.abs(sum1 - sum2); minDiff = Math.min(minDiff, diff); } // 尝试所有垂直切割线 for (int j = 1; j < m; j++) { int sum1 = 0; for (int col = 0; col < j; col++) { for (int row = 0; row < n; row++) { sum1 += a[row][col]; } } int sum2 = totalSum - sum1; int diff = Math.abs(sum1 - sum2); minDiff = Math.min(minDiff, diff); } return minDiff;