算法30----三维形体的表面积、周长
一、表面积
1、题目:
在 N * N
的网格上,我们放置一些 1 * 1 * 1
的立方体。
每个值 v = grid[i][j]
表示 v
个正方体叠放在单元格 (i, j)
上。
返回结果形体的总表面积。
示例 1:
输入:[[2]] 输出:10
示例 2:
输入:[[1,2],[3,4]] 输出:34
示例 3:
输入:[[1,0],[0,2]] 输出:16
示例 4:
输入:[[1,1,1],[1,0,1],[1,1,1]] 输出:32
示例 5:
输入:[[2,2,2],[2,1,2],[2,2,2]] 输出:46
提示:
1 <= N <= 50
0 <= grid[i][j] <= 50
2、思路:
顶面积底面积一样计算,侧面积从0,0点开始遍历(不分层),到任何一个点,sum+4*节点个数-2*(min(左侧方块个数,当前方块个数))-2(min(下侧方块个数,当前方块个数));应该不难理解,就是叠积木,把重叠的面积减掉;
3、代码:
def surfaceArea(self, grid): """ :type grid: List[List[int]] :rtype: int """ if not grid: return 0 count = 0 a,b,sumn = 0,0,0 for i,row in enumerate(grid): for j,col in enumerate(row): sumn += col if not col: continue count+=1 if i > 0: a+=min(grid[i-1][j],col) if j > 0: b+=min(grid[i][j-1],col) return sumn*4+count*2-(a+b)*2
思路2:前面面积 (每一列最大值相加)+ 侧面面积(每一行最大值相加) + 上面面积(N*M)
代码2:
N , M = map(int,input().split()) arr = [[0] * M for i in range(N)] for i in range(N): arr[i] = list(map(int,input().split())) left , forward = 0 , 0 ##一个侧面面积 for i in range(N): max0 = 0 for j in range(M): if max0 < arr[i][j]: max0 = arr[i][j] left += max0 reverse_arr = list(zip(*arr)) #一个前面面积 for i in range(N): max0 = 0 for j in range(M): if max0 < reverse_arr[i][j]: max0 = reverse_arr[i][j] forward += max0 #三个面积相加*2 res = (N * M + left + forward) * 2 print(res)
二、周长:
1、题目:
给定一个包含 0 和 1 的二维网格地图,其中 1 表示陆地 0 表示水域。网格中的格子水平和垂直方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
示例 :
[[0,1,0,0], [1,1,1,0], [0,1,0,0], [1,1,0,0]] 答案: 16 解释: 它的周长是下面图片中的 16 个黄色的边:
2、思路
1的个数*4 - 重叠的1的个数
3、代码:
def islandPerimeter(self, grid): """ :type grid: List[List[int]] :rtype: int """ if not grid: return 0 m = len(grid) n = len(grid[0]) count,repeat = 0,0 for i in range(m): for j in range(n): if grid[i][j] == 1: count+=1 if j+1<n: repeat += grid[i][j+1] if j-1>=0: repeat += grid[i][j-1] if i-1>=0: repeat += grid[i-1][j] if i+1<m: repeat += grid[i+1][j] return count*4 - repeat