文章目录
深度优先搜索练习题
视频链接:https://www.bilibili.com/video/BV1pk4y1z76B?p=3
草地寻人
题目
蒜头君和他的朋友周末相约去召唤师峡谷踏青。他们发现召唤师峡谷的地图是由一块一块格子组成的,有的格子上是草丛,有的是空地。草丛通过上下左右4个方向扩展其他草丛形成一片草地, 任何一片草地中的格子都是草丛,并且所有格子之间都能通过,上下左右连通。如果用‘#"代表草丛,.代表空地,下面的峡谷中有2片草地。
##..
..##
处在同一个草地的2个人可以相互看到,空地看不到草地里面的人。他们发现有一个朋友不见了,现在需要分头去找,每个人负责一片草地,蒜头君想知道他们至少需要多少人。
输入格式
第一行输入n,m表示峡谷大小。
接下来输入n行字符串表示峡谷的地形。
输入格式
输出至少需要多少人。
代码
direction = [[-1,0],[0,-1],[1,0],[0,1]]
def dfs(x,y):
maze[x][y] = '.'
for i in range(0,len(direction)):
tx = x + direction[i][0]
ty = y + direction[i][1]
if tx >= 0 and tx < n and ty >= 0 and ty < m and maze[tx][ty] == '#':
dfs(tx,ty)
n , m = [int(i) for i in input("").split()]
maze = []
for i in range(0,n):
list1 = list(input())
maze.append(list1)
cnt = 0
for i in range(0,n):
for j in range(0,m):
if maze[i][j] == "#":
cnt = cnt+1
dfs(i,j)
print(cnt)
测试
迷宫地图
题目
有一个n*m的地图,地图由’.’(可同行的路)、‘#’(迷宫的墙)、‘s’(起点)、’e‘(终点),求能走到终点的路径条数
输入格式
n m(行 列)
字符地图
输出格式
数字(路径条数)
代码
def dfs(x,y):
if maze[x][y] == 'e':
global cnt
cnt = cnt + 1
return 1
vis[x][y] = 1
maze[x][y] = 'm'
for i in range(0,len(direction)):
tx = x + direction[i][0]
ty = y + direction[i][1]
if tx >= 0 and tx < n and ty >= 0 and ty < m and maze[tx][ty] != '#' and vis[tx][ty] == 0:
dfs(tx,ty)
vis[x][y] = 0
maze[x][y] = '.'
n , m = [int(i) for i in input("").split()]
maze = []
for i in range(0,n):
list1 = list(input())
maze.append(list1)
vis = []
for i in range(0,n):
list1 = [0]*m
vis.append(list1)
direction = [[-1,0],[0,-1],[1,0],[0,1]]
cnt = 0
for i in range(0,n):
for j in range(0,m):
if maze[i][j] == 's':
dfs(i,j)
print(cnt)
测试
生日蛋糕
题目
这块蛋糕是由R x C的网格构成,每个网格上面都放有不同的水果。蒜头君把这些水果分为两类,一类是自己喜欢吃的水果,用’#"来表示;一类是自己不喜欢吃的水果,用’.'来表示。
蒜头君对切出的蛋糕有如下要求:
●切出的蛋糕连成一块(可以不为矩形,但必须在网格上连通)
●切出的蛋糕只包含自己喜欢吃的水果请问,蒜头君最大可以吃到多大的蛋糕?
输入格式
n m(行 列)
字符地图
输出格式
数字(最大蛋糕数)
代码
def dfs(x,y):
maze[x][y] = '.'
global cnt
cnt = cnt + 1
for i in range(0,len(direction)):
tx = x +direction[i][0]
ty = y +direction[i][1]
if tx >= 0 and tx < n and ty >= 0 and ty < m and maze[tx][ty] == '#':
dfs(tx,ty)
return cnt
n , m = [int(i) for i in input().split()]
maze = []
for i in range(0,n):
list1 = list(input())
maze.append(list1)
direction = [[-1,0],[0,-1],[1,0],[0,1]]
ans = []
for i in range(0,n):
for j in range(0,m):
if maze[i][j] == '#':
cnt = 0
num = dfs(i,j)
ans.append(num)
print(ans)
print(max(ans))
测试
直系后代
题目
统计每位祖先有多少直系后代
输入格式
输入n(表示家谱中的总人数)
读入n-1行,每行有2个整数x,y(表示x是y的父母)
输出格式
输出n行,每行有一个整数,表示第i个人有多少个直系后代
代码
##dfs寻找x的后代
def dfs(x):
cnt = 0
for j in range(0,n-1):
if maze[j][0]==x:
## 一旦在父列中出现,说明它有一个后代
cnt = cnt + 1
## 再来查找该后代的后代
cnt = cnt + dfs(maze[j][1])
return cnt
n = int(input())
maze = []
for i in range(0,n-1):
list1 = [int(j) for j in input().split()]
maze.append(list1)
for i in range(1,n+1):
print(i,dfs(i))
测试
马走三步棋盘
题目
马走日子字形,找出马走三步内可以达到的点
输入格式
n m(行 列)
x y(马的初始位置)
输出格式
输出棋盘(#表示马可能到达的点,.表示其余的位置)
代码
def dfs(x,y,step):
if(step == 4):
return 1
for i in range(0,len(direction)):
tx = x + direction[i][0]
ty = y + direction[i][1]
if tx >= 0 and tx < n and ty >= 0 and ty < m:
maze[x][y] = '#'
dfs(tx,ty,step+1)
n , m = [int(i) for i in input().split()]
x , y = [int(i) for i in input().split()]
maze = []
for i in range(0,n):
list1 = ['.']*m
maze.append(list1)
maze[x-1][y-1] = '*'
direction = [[-2,-1],[-1,-2],[1,-2],[2,-1],[2,1],[1,2],[-1,2],[-2,1]]
dfs(x-1,y-1,0)
for i in range(0,n):
str1 = ''
for j in range(0,m):
str1 = str1 + maze[i][j]
print(str1)
测试
迷宫2人相遇
题目
王子移动一次沿一个方向走2步,公主一个方向走一步,问能否相遇?
输入格式
n m(行 列)
地图(.路,#墙,w王子的位置,g公主的位置)
输出格式
yes/no
代码
王子可以到达哪些点,公主可以到达哪些点,是否有重复的点
##深拷贝
import copy
def dfsw(x,y):
for i in range(0,len(direction_w2)):
tx = x + direction_w2[i][0]
ty = y + direction_w2[i][1]
if tx >= 0 and tx < n and ty >=0 and ty < m and mazew[tx][ty] == '.':
mazew[tx][ty] = 'm'
dfsw(tx,ty)
def dfsg(x,y):
for i in range(0,len(direction_g1)):
tx = x + direction_g1[i][0]
ty = y + direction_g1[i][1]
if tx >= 0 and tx < n and ty >=0 and ty < m and mazeg[tx][ty] =='.':
mazeg[tx][ty] = 'm'
dfsg(tx,ty)
n , m = [int(i) for i in input().split()]
mazew = []
for i in range(0,n):
list1 = list(input())
mazew.append(list1)
mazeg = copy.deepcopy(mazew)
direction_g1 = [-1,0],[0,-1],[1,0],[0,1]
direction_w2 = [-2,0],[0,-2],[2,0],[0,2]
for i in range(0,n):
for j in range(0,m):
##王子的路径
if mazew[i][j] == 'w':
dfsw(i,j)
##公主的路径
if mazeg[i][j] == 'g':
dfsg(i,j)
##输出王子的路径
for i in range(0,n):
print(mazew[i])
print('------')
##输出公主的路径
for i in range(0,n):
print(mazeg[i])
flag = 0
for i in range(0,n):
for j in range(0,m):
if mazew[i][j]== 'm' and mazeg[i][j] == 'm':
flag = 1
break
if flag == 1:
print("yes")
else:
print("no")
测试
n名员工最少时间完成工作
题目
2020年,蒜头君自己开了一家拥有N个员工的大公司。每天,蒜头君都要分配N项工作给他的员工,但是,由于能力的不同,每个人对处理相同工作所需要的时间有所差异。
众所周知,蒜头君是一个非常重视效率的人,他想知道该如何分配工作,才能使得完成所有工作的时间总和最小(每个员工只可以被分配到一个工
作)。但是我们也都知道,蒜头君不是一般的懒,所以蒜头君找到了你,请你拯救一下蒜头君吧!
输入格式
第一行输入一个整数N,代表有N个员工,员工编号从1到N(1≤N≤10)。
接着输入一个N x N的二维矩阵task,
t
a
s
k
[
i
]
[
j
]
task[i][j]
task[i][j](0≤task[i[j]≤1000)指的是第i项工作如果由j号员工完成所需要的时间。
输出格式
输出一个整数,代表所需要的最少时间总和。
代码
def dfs(x,t):
global ans
if x==n:
if t < ans:
ans = t
return 1
for i in range(0,n):
if col[i] == 0:
col[i] = 1
dfs(x+1,t+maze[x][i])
col[i] = 0
n = int(input())
maze = []
for i in range(0,n):
list1 = [int(j) for j in input().split()]
maze.append(list1)
col = []
for i in range(0,n):
col.append(0)
ans = 80
dfs(0,0)
print(ans)