深度优先搜索练习题(计蒜客-蓝桥杯国赛训练营)

本文通过一系列的编程练习题展示了深度优先搜索(DFS)在解决迷宫、寻人、蛋糕分块、家谱分析和棋盘游戏等复杂问题中的应用。DFS作为一种重要的图遍历算法,能够有效地在连通组件中寻找路径或进行计数。在不同的题目中,DFS被用于找出最大连通区域、计算路径数量、确定可达点集以及优化工作分配,体现了其在解决问题上的灵活性和实用性。
摘要由CSDN通过智能技术生成

深度优先搜索练习题

视频链接: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)

测试

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值