蓝桥杯 迷宫 二叉树 真题

简介: 蓝桥杯 迷宫 二叉树 真题

距离蓝桥杯58天


学习算法是为了提升我们的思维能力


坚持算法训练不仅可以帮助我们度过笔试的那一关 人生的各项加成也很多


真题训练1(编程题):完全二叉树的权值>>考察对二叉树深度, 结点, 关系的掌握


69ffe45697394c029dbc092a97b90c4d.png


首先 我们需要了解完全二叉树的定义:除去最后一层为满二叉树+最后一层结点从左往右排列;满二叉树:除最后一层无任何子结点外,每一层上的所有结点都有两个子结点的二叉树


掌握两者的深度计算公式:若已知二叉树有n个结点


完全二叉树:depth=[log(2,n+1)]  (向下取整)[这个可以记忆一下]


满二叉树:depth=log(2,n+1)[这个可以直接推导]


最后掌握满二叉树第i层有2^(i-1)个结点 即可解决


因此对于本题 我们可以创建一个列表s s[i]用于储存第i行的总和


已知每行结点的个数 要求每行的总和只需知道每行首尾元素的索引


观察易得每行首元素的索引呈2的等比数列排布 因而尾元素索引可求


故每行总和可求


题目要求最大的权值对应的深度 只需利用index 和max函数


max函数都明白,index函数 指的是序列中首次出现指定元素的索引


故我们先获取max 再利用index 便是最大值相同的情况的最小深度


7c150d7cd93a4410a9f1bb8cce28d8f9.png

N=int(input())
import math
depth=int(math.log(N,2))+1
s=[0]*depth
res=list(map(int,input().strip().split()))
for i in range(depth-1):
    s[i]=sum(res[2**i-1:2**(i+1)-1])
s[depth-1]=sum(res[2**(depth-1)-1:])
print(s.index(max(s))+1)
##math.log(x,y)=m 等价于 y^m=x

真题训练2:迷宫>>考察BFS

dcf83c9fe4fb4bbaa88bcda89fd77adf.png

图片中的是题目给出的例子,题目的迷宫在这里


问题分析:BFS常用来解决迷宫最短路径问题    原因:C语言对这个的解释(传送门)


并建议去<<算法图解>>第六章一看


对于本道题 BFS采用队列 开始状态(0,0)入队 然后四个方向依次试探


可通过便入队 同时创建父子结点关系(即记录一层父子节点关系)当广度搜索层数增加到最外层出现终点,停止搜索。


本题不仅要求最短路径(实际上没有但应当必须掌握),还要输出路径并且此路径的字典序最小


因此我们需要回溯:由于先前记录了父子结点的层次关系 且迷宫上每移动一步就创建了一层父子关系 从终点回溯到终点 经历了几层父子关系就是路径长度(而且是最短的)


字典序最小:到达终点的路径有很多种,即通过建立不同的父子关系能达到相同的终点,我们要找到其中字典序最小的(D<L<R<U) 简言之,如果我当前处在位置(x,y),如果上下左右都通(且还没有被访问过),优先走D其次是L再次是R最后是U,就优先建立和下侧的父子关系其次是左侧再次是右侧最后是上侧

maze_str="""01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000"""
dirs=[lambda x,y:(x+1,y),
      lambda x,y:(x,y-1),
      lambda x,y:(x,y+1),
      lambda x,y:(x-1,y)]#字典序最小 因此函数排列顺序有要求 D L R U 
def f(x1,y1,x2,y2):#x是行,y是列
    if x2-x1>0:
        return 'D'
    elif x2-x1<0:
        return 'U'
    elif y2-y1>0:
        return 'R'
    else: 
        return 'L'
maze=maze_str.split()
from queue import Queue#导入队列模板
row,col=len(maze)-1,len(maze[0])-1
start,end=(0,0),(row,col)
path=Queue()
path.put(start)
pre={(0,0):(0,0)}
count=0#路径长度
while not path.empty():#不为空就找 如果为空了说明没有路径前往终点
    cur=path.get()#出队
    if cur==end:
        p=end
        s=''
        while p!=start:
            s+=f(pre[p][0],pre[p][1],p[0],p[1])#打印路径
            p=pre[p]#回溯 
            count+=1
        print(count)
        print(s[::-1])#由于是回溯,路径需要取反
        break
    else:
        for dir in dirs:
            next_cur=dir(cur[0],cur[1])
            x,y=next_cur[0],next_cur[1]#创建父子节点关系(前提没访问过+在迷宫内+非障碍物)
            if next_cur not in pre.keys() and 0<=x<=row and 0<=y<=col and int(maze[x][y])==0 :
                pre[next_cur]=cur
                path.put(next_cur)
#count=186
#路径DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR

DFS模板:(和本题无关,但是可以解决最短路径长和方案种数问题

n,m,t=map(int,input().strip().split())
point=[[0]*(m+1) for i in range(n+1)]
sx,sy,fx,fy=map(int,input().strip().split())
#设置障碍物
for k in range(t):
    tmp=list(map(int,input().strip().split()))
    point[tmp[0]][tmp[1]]=1
dx=[1,-1,0,0]
dy=[0,0,1,-1]
def judge(newx,newy):
    #越界,障碍物或已访问
    if newx>n or newx<=0 or newy>m or newy<=0:
        return False
    if point[newx][newy]==1:
        return False
    return True
count=0
min_step=float('inf')
def dfs(x,y,step):
    global count,min_step
    if x==fx and y==fy:
        count+=1
        min_step=min(step,min_step)
        return True
    else:                       
        for i in range(4):
            newx,newy=x+dx[i],y+dy[i]
            if judge(newx,newy):
                point[x][y]=1
                dfs(newx,newy,step+1)
                point[x][y]=0
dfs(sx,sy,0)
print(count)#路径总数
print(min_step)#最短路径长

我是小郑 正在备战蓝桥杯 正在奔赴热爱 奔赴山海


相关文章
|
6月前
|
Java
P9242 [蓝桥杯 2023 省 B] 接龙数列JAVA,边权为1的最短路问题,洛谷P9242 [蓝桥杯 2023 省 B] 接龙数列​编辑力扣1926.迷宫离入口最近的出口力扣433.
P9242 [蓝桥杯 2023 省 B] 接龙数列JAVA,边权为1的最短路问题,洛谷P9242 [蓝桥杯 2023 省 B] 接龙数列​编辑力扣1926.迷宫离入口最近的出口力扣433.
|
算法
蓝桥杯:真题 迷宫
蓝桥杯:真题 迷宫
79 0
|
存储 索引
蓝桥杯丨二叉树
蓝桥杯丨二叉树
74 0
|
Python
蓝桥杯-迷宫(19年)-python
蓝桥杯-迷宫(19年)-python
81 0
|
定位技术 Python
蓝桥杯-迷宫(17年)-python
蓝桥杯-迷宫(17年)-python
91 0
|
存储 移动开发 Python
【蓝桥杯集训·每日一题】AcWing 3555. 二叉树
文章目录 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 三、知识风暴 最近公共祖先
91 0
蓝桥杯2019年第十届JavaB组真题题目+解析+代码+答案:5.迷宫
蓝桥杯2019年第十届JavaB组真题题目+解析+代码+答案:5.迷宫
147 0
蓝桥杯2019年第十届JavaB组真题题目+解析+代码+答案:5.迷宫
|
算法 C语言 索引
蓝桥杯 迷宫 二叉树 真题
蓝桥杯 迷宫 二叉树 真题
126 0
蓝桥杯 迷宫 二叉树 真题
|
7月前
|
人工智能 算法 Java
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1005 数字游戏
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1005 数字游戏
115 0