101. 孤岛总面积
深搜
python
DIR = [[0,1],[1,0],[0,-1],[-1,0]]
def dfs(graph,x,y):
if not graph[x][y]:
return
graph[x][y] = 0
for i in range(4):
nextx = x + DIR[i][0]
nexty = y + DIR[i][1]
if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
continue
dfs(graph,nextx,nexty)
def main():
n,m = map(int,input().split())
graph = []
for _ in range(n):
graph.append(list(map(int,input().split())))
# visited = [[0]*m for _ in range(n)]
# 孤岛的定义:周围不接触边缘的岛屿
# 一个思路是,将周围接触边缘的岛屿全部置为0,最终统计graph中1的个数
# 遍历4条边,将其中相邻的陆地岛屿全部置为0
# 这里不需要visited,因为我们直接修改了graph,相当于同步完成了visited工作
for i in range(n):
if graph[i][0]:
dfs(graph,i,0)
if graph[i][m-1]:
dfs(graph,i,m-1)
for j in range(m):
if graph[0][j]:
dfs(graph,0,j)
if graph[n-1][j]:
dfs(graph,n-1,j)
res = sum([sum(graph[i]) for i in range(n)])
print(res)
if __name__ == '__main__':
main()
广搜
python
DIR = [[0,1],[1,0],[0,-1],[-1,0]]
def bfs(graph,x,y):
queue = []
queue.append([x,y])
while queue:
x,y = queue.pop()
graph[x][y] = 0
for i in range(4):
nextx = x + DIR[i][0]
nexty = y + DIR[i][1]
if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
continue
if graph[nextx][nexty]:
queue.append([nextx,nexty])
def main():
n,m = map(int,input().split())
graph = []
for _ in range(n):
graph.append(list(map(int,input().split())))
# visited = [[0]*m for _ in range(n)]
# 孤岛的定义:周围不接触边缘的岛屿
# 一个思路是,将周围接触边缘的岛屿全部置为0,最终统计graph中1的个数
# 遍历4条边,将其中相邻的陆地岛屿全部置为0
# 这里不需要visited,因为我们直接修改了graph,相当于同步完成了visited工作
for i in range(n):
if graph[i][0]:
bfs(graph,i,0)
if graph[i][m-1]:
bfs(graph,i,m-1)
for j in range(m):
if graph[0][j]:
bfs(graph,0,j)
if graph[n-1][j]:
bfs(graph,n-1,j)
res = sum([sum(graph[i]) for i in range(n)])
print(res)
if __name__ == '__main__':
main()
102. 沉没孤岛
可以构造一个visited,将周边全部记录为1,中间的孤岛的visited不查看,最后全部置为0
但是也可以直接使用graph,将非孤岛置为2,最后还原!
深搜
python
DIR = [[0,1],[1,0],[0,-1],[-1,0]]
def dfs(graph,x,y):
if graph[x][y] != 1:
return
graph[x][y] = 2
for i in range(4):
nextx = x + DIR[i][0]
nexty = y + DIR[i][1]
if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
continue
dfs(graph,nextx,nexty)
def main():
n,m = map(int,input().split())
graph = []
for _ in range(n):
graph.append(list(map(int,input().split())))
for i in range(n):
if graph[i][0]:
dfs(graph,i,0)
if graph[i][m-1]:
dfs(graph,i,m-1)
for j in range(m):
if graph[0][j]:
dfs(graph,0,j)
if graph[n-1][j]:
dfs(graph,n-1,j)
for i in range(n):
for j in range(m):
if graph[i][j] == 1:
graph[i][j] = 0
elif graph[i][j] == 2:
graph[i][j] = 1
for r in graph:
print(' '.join(map(str,r)))
if __name__ == '__main__':
main()
广搜
python
DIR = [[0,1],[1,0],[0,-1],[-1,0]]
def bfs(graph,x,y):
queue = []
queue.append([x,y])
while queue:
x,y = queue.pop()
graph[x][y] = 2
for i in range(4):
nextx = x + DIR[i][0]
nexty = y + DIR[i][1]
if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
continue
if graph[nextx][nexty]==1:
queue.append([nextx,nexty])
def main():
n,m = map(int,input().split())
graph = []
for _ in range(n):
graph.append(list(map(int,input().split())))
for i in range(n):
if graph[i][0]:
bfs(graph,i,0)
if graph[i][m-1]:
bfs(graph,i,m-1)
for j in range(m):
if graph[0][j]:
bfs(graph,0,j)
if graph[n-1][j]:
bfs(graph,n-1,j)
for i in range(n):
for j in range(m):
if graph[i][j] == 1:
graph[i][j] = 0
elif graph[i][j] == 2:
graph[i][j] = 1
for r in graph:
print(' '.join(map(str,r)))
if __name__ == '__main__':
main()
103. 高山流水
暴力思路:遍历每一个节点,对于每个节点使用深搜或者广搜,看看是否会达到边界(时间复杂度)
逆向思考:我们找到第一边界和第二边界从低往高走的所有点,两个的交集就是我们要找的"高山"。(时间复杂度()由于不会重复访问同一个节点,所以实际复杂度更低
)
python
DIR = [[0,1],[1,0],[0,-1],[-1,0]]
def dfs(graph,visited,x,y):
if visited[x][y]:
return
visited[x][y] = 1
for i in range(4):
nextx = x + DIR[i][0]
nexty = y + DIR[i][1]
if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
continue
if graph[x][y] <= graph[nextx][nexty]:
dfs(graph,visited,nextx,nexty)
def main():
n,m = map(int,input().split())
graph = []
for _ in range(n):
graph.append(list(map(int,input().split())))
isfirst = [[0]*m for _ in range(n)]
issecond = [[0]*m for _ in range(n)]
for i in range(n):
dfs(graph,isfirst,i,0)
dfs(graph,issecond,i,m-1)
for j in range(m):
dfs(graph,isfirst,0,j)
dfs(graph,issecond,n-1,j)
for i in range(n):
for j in range(m):
if isfirst[i][j] and issecond[i][j]:
print(f"{i} {j}")
if __name__ == '__main__':
main()
104. 建造最大岛屿
python
DIR = [[0,1],[1,0],[0,-1],[-1,0]]
count = 0
def dfs(graph,visited,x,y,mask):
global count
if visited[x][y] or graph[x][y] != 1:
return
visited[x][y] = 1
graph[x][y] = mask
count +=1
for i in range(4):
nextx = x + DIR[i][0]
nexty = y + DIR[i][1]
if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
continue
dfs(graph,visited,nextx,nexty,mask)
def main():
global count
n,m = map(int,input().split())
graph = []
for _ in range(n):
graph.append(list(map(int,input().split())))
visited = [[0]*m for _ in range(n)]
d = {0:0}
mask = 2
res = 0
for i in range(n):
for j in range(m):
if graph[i][j] and not visited[i][j]:
# 统计岛屿面积
count = 0
dfs(graph,visited,i,j,mask)
d[mask] = count
mask +=1
for i in range(n):
for j in range(m):
if not graph[i][j]:
tmp = set()
for c in range(4):
nextx = i + DIR[c][0]
nexty = j + DIR[c][1]
if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
continue
if graph[nextx][nexty]>1:
tmp.add(graph[nextx][nexty])
res = max(res,1+sum([d[x] for x in tmp]))
if res == 0:
# 注意:d中包含{0:0},所以需要排除0
res = max(d.values())
print(res)
if __name__ == '__main__':
main()