用flag=True表名这片岛屿已经满足了“不被淹没”的条件。
def dfs(grid,i,j):
if not 0 <= i < len(grid) or not 0 <= j < len(grid[0]) or grid[i][j] != '#':
return
if cnt == 4:
flag = True
if flag == False:
if grid[i+1][j] == '#' and grid[i-1][j] == '#' and grid[i][j+1] == '#' and grid[i][j-1]:
cnt += 1
n = int(input())
grid = []
ans = 0
vis = [[0]*n for i in range(n)]
for i in range(n):
nei = []
nei = list(map(str, input().split(" ")))
grid.append(nei)
def dfs(grid, i, j):
global flag
global vis
if not 0 <= i < len(grid) or not 0 <= j < len(grid[0]) or grid[i][j] != '#' or vis[i][j] == 1:
return
vis[i][j] = 1
if grid[i + 1][j] == '#' and grid[i - 1][j] == '#' and grid[i][j + 1] == '#' and grid[i][j - 1] == '#':
flag = True
dfs(grid, i - 1, j)
dfs(grid, i + 1, j)
dfs(grid, i, j + 1)
dfs(grid, i, j - 1)
for i in range(n):
for j in range(n):
if grid[i][j] == '#' and vis[i][j] == 0:
flag = False
dfs(grid, i, j)
if flag == False:
ans += 1
print(ans)
题解
为什么要在深搜之前加限制条件呢,因为可能是会有数组越界条件
import os
import sys
# 请在此输入您的代码
sys.setrecursionlimit(60000)
n = int(input())
mp = [list(input()) for i in range(n)]#海域照片
vis = [[0]*n for i in range(n)]
ans = 0#被淹没的岛屿的数量
def dfs(x,y):
dic = [(0,1),(0,-1),(1,0),(-1,0)]
global flag
global vis
global mp
vis[x][y]=1
if mp[x][y+1]=='#' and mp[x][y-1]=='#' and mp[x+1][y]=='#' and mp[x-1][y]=='#':
flag=1
for i in range(4):
nx = x+dic[i][0]
ny = y+dic[i][1]
if vis[nx][ny]==0 and mp[nx][ny]=='#':
dfs(nx,ny)
for i in range(n):
for j in range(n):
if vis[i][j]==0 and mp[i][j]=='#':
flag=0
dfs(i,j)
if flag==0:
ans+=1
print(ans)
看了题解之后的答案
n = int(input())
grid = []
ans = 0
vis = [[0] * n for i in range(n)]
# for i in range(n):
# nei = []
# nei = list(map(str, input().split(" ")))
# grid.append(nei)
grid = [list(input()) for i in range(n)]
def dfs(grid, i, j):
dic = [[0, 1], [0, -1], [1, 0], [-1, 0]]
global flag
global vis
if not 0 <= i < len(grid) or not 0 <= j < len(grid[0]) or grid[i][j] != '#' or vis[i][j] == 1:
return
vis[i][j] = 1
if grid[i + 1][j] == '#' and grid[i - 1][j] == '#' and grid[i][j + 1] == '#' and grid[i][j - 1] == '#':
flag = True
for k in range(4):
nx = i + dic[k][0]
ny = j + dic[k][1]
if vis[nx][ny] == 0 and grid[nx][ny] == '#':
dfs(grid, nx, ny)
for i in range(n):
for j in range(n):
if grid[i][j] == '#' and vis[i][j] == 0:
flag = False
dfs(grid, i, j)
if not flag:
ans += 1
print(ans)
差别就是sys.setrecursionlimit(60000)
另一个比较好看的题解
# 连通性判断:
# 连通性问题,计算步骤:
# 遍历一个连通块(找到这个连通块中所有的'#',标记已经搜过,不用再搜)
# 再遍历下一个连通块......
# 遍历完所有连通块,统计有多少个连通块。
import sys
sys.setrecursionlimit(1000000)
# 因为这个只是判断我当前这个x,y是不是高地,并不是DFS搜索结束的条件,如果加return,那就有可能导致有陆地没有被搜索到过
# 这个DFS函数的目的就是去搜索所有陆地,没有用到回溯的功能
def dfs(x, y):
d = [(0, -1), (0, 1), (-1, 0), (1, 0)]
global flag
vis[x][y] = 1
if mp[x][y - 1] == '#' and mp[x][y + 1] == '#' and mp[x - 1][y] == '#' and mp[x + 1][y] == '#':
flag = 1
for i in range(4):
nx = x + d[i][0]
ny = y + d[i][1]
if vis[nx][ny] == 0 and mp[nx][ny] == '#':
dfs(nx, ny)
n = int(input())
mp = []
for i in range(n):
mp.append(list(input())) # mp二维数组存图
# mp = [[''] * n for i in range(n)]
# for i in range(n):
# mp[i] = list(input())
vis = [[0] * n for i in range(n)] # vis数组用于判断图上的点是否走过,1是走过,0是没有走过
ans = 0
for i in range(n):
for j in range(n): # 遍历每一个点
if vis[i][j] == 0 and mp[i][j] == '#': # 如果这个点没有走过,并且这个点是岛屿
flag = 0 # flag 是判断这个岛屿是不是高地,flag = 0不是,flag = 1是
dfs(i, j)
if flag == 0: # 如果这个岛屿被吞没,ans += 1
ans += 1
print(ans)
更加完整的
import sys
sys.setrecursionlimit(1000000)
# grid = [list(input()) for i in range(n)]
# 0<= xx < len(grid) and 0 <= yy < len(grid[0]) and
def dfs(x, y):
d = [(0, -1), (0, 1), (-1, 0), (1, 0)]
global flag
vis[x][y] = 1
if mp[x][y - 1] == '#' and mp[x][y + 1] == '#' and mp[x - 1][y] == '#' and mp[x + 1][y] == '#':
flag = 1
for i in range(4):
nx = x + d[i][0]
ny = y + d[i][1]
if vis[nx][ny] == 0 and mp[nx][ny] == '#' and 0<= nx < len(mp) and 0 <= ny < len(mp[0]):
dfs(nx, ny)
n = int(input())
mp = [list(input()) for i in range(n)]
vis = [[0] * n for i in range(n)]
ans = 0
for i in range(n):
for j in range(n):
if vis[i][j] == 0 and mp[i][j] == '#':
flag = 0
dfs(i, j)
if flag == 0:
ans += 1
print(ans)