三维形体的表面积
题目
在 N * N 的网格上,我们放置一些 1 * 1 * 1 的立方体。
每个值 v = grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。
请你返回最终形体的表面积。
题目解释
在一个j,i的坐标中的每个格子里放 v=grid[i][j]个立方体,一般一个立方体有6面,因此单独一个立方体表面积为6,而如果两个立方体挨着,就需要减少两个面的面积 = 2*6 - 2.
就题目而言,会挨着的表面积上下左右,对于上下的表面积覆盖值可以用2,3,4个立方体放一个格子来推导,2个立方体竖直放在一起会有2个面被盖住,3个立方体放一起会有4个面被盖住,4个立方体放在一起会有6个面会被盖住,因此竖直放时会被盖住的面为 = 2*(n-1)个面。
而左右覆盖的问题就是求两个挨着格子的竖直格子最少的一个格子的个数。
求解
/**
* 2 = 2 = 2*(n-1)
* 3 = 4
* 4 = 6
*
* @param grid
* @return
*/
public static int surfaceArea(int[][] grid) {
int s = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
int temp = grid[i][j];
int tempS;
if (temp <= 1) {
tempS = temp * 6;
} else {
tempS = temp * 6 - 2 * (temp - 1);
}
// 不管怎么覆盖,都按照左右不覆盖都问题解决
s += tempS;
// 减去上下挨着的情况
if (i - 1 >= 0 && grid[i - 1][j] > 0) {
int rs = Math.min(temp, grid[i - 1][j]);
s -= rs * 2;
}
// 减去左右挨着的情况
if (j - 1 >= 0 && grid[i][j - 1] > 0) {
int ts = Math.min(temp, grid[i][j - 1]);
s -= ts * 2;
}
System.out.print(StrUtil.format("[i={} j={} v={} s={}] ", i, j, temp, tempS));
}
System.out.println("s = " + s);
}
return s;
}
打印过程
[i=0 j=0 v=1 s=6] [i=0 j=1 v=2 s=10] s = 14
[i=1 j=0 v=3 s=14] [i=1 j=1 v=4 s=18] s = 34
34
总结
该类题目主要找规律就可以求解