蓝桥杯 Python 组省赛夺奖班-3.4 二叉树

本文展示了使用Python解决几种不同的算法问题,包括构建完全二叉树并计算权值、FBI树的构造与后序遍历、根据天干地支计算年份、找出整数数组的最大间隙以及扫雷游戏的实现。这些示例涵盖了数据结构如二叉树和数组,以及简单的算法应用。
摘要由CSDN通过智能技术生成

一、完全二叉树的权值

题目

请添加图片描述

思路

首先根据输入的节点数n推出完全二叉树的深度k,因为完全二叉树并不是满二叉树,对于最后一层节点的处理需要判断是否满,但是这里我直接对最后一层切到尾只需要判断是否是最后一层。
通过手动推导有以下结论【约定节点和深度都从1开始】:

  • 第i层节点为 2^(i-1) ~ 2^(i) - 1
  • k层满二叉树的节点总数为 2^(n) - 1

然后不难得出下面的代码

代码

import math
n = int(input())
k = math.ceil(math.log(n+1,2))
a = [0]*(n+1)
b = [0]+list(map(int,input().split()))
for i in range(1,k+1):
    if i == k:
        a[i] = sum(b[2**(i-1):])
    else:
        a[i] = sum(b[2**(i-1):2**i])
print(a.index(max(a)))

二、FBI树

题目

请添加图片描述

思路

直接使用列表list模拟二叉树,例如,节点编号为p的左子树为2p、右子树为2p+1。然后首先递归建立二叉树,注意建立二叉树时可以通过判断左右子树的类型判断节点的类型。

代码

n = int(input())
a = input()
t = [""]*5500
def build(p,s):
    if len(s) == 1:
        if "0" in s and "1" in s:
            t[p] = "F"
        elif "0" in s:
            t[p] = "B"
        else:
            t[p] = "I"
        return 
    else:
        lt = s[:len(s)//2]
        rt = s[len(s)//2:]
        build(2*p,lt)
        build(2*p+1,rt)
        if t[2*p] == "B" and t[2*p+1] == "B":
            t[p] = "B"
        elif t[2*p] == "I" and t[2*p+1] == "I":
            t[p] = "I"
        else:
            t[p] = "F"
def postorder(p):
    if t[2*p] != "":
        postorder(2*p)
    if t[2*p+1] != "":
        postorder(2*p+1)
    print(t[p],end = "")
build(1,a)
postorder(1)

三、天干地支

题目

请添加图片描述

思路

直接组合天干和地支即可,这里观察到2020年为庚子年,天干十年一循环,地支十二年一循环。直接取模选即可。这里通过计算器计算得2020%12 = 4。后面的天干地支直接按照顺序填即可。
请添加图片描述

代码
tian = {0:"geng",1:"xin",2:"ren",3:"gui",4:"jia",5:"yi",6:"bing",7:"ding",8:"wu",9:"ji"}
di = {4:"zi",5:"chou",6:"yin",7:"mao",8:"chen",9:"si",10:"wu",11:"wei",0:"shen",1:"you",2:"xu",3:"hai"}
n = int(input())
print(tian[n%10]+di[n%12])

四、最大间隙

题目

请添加图片描述

思路

模拟+节省空间

代码

n = int(input())
a = list(map(int,input().split()))
ans = 0
for i in range(1,n):
    if ans < a[i] - a[i-1]:
        ans = a[i] - a[i-1]
print(ans)

五、扫雷

题目

请添加图片描述

思路

外圈加零,直接算即可,相比起区分九种情况简单多了。

代码

n,m = list(map(int,input().split()))
a = [[0]*(m+2)]
for i in range(n):
    a.append([0]+list(map(int,input().split()))+[0])
a.append([0]*(m+2))
##ans = [[0]*(m+2) for _ in range(n+2)]
for i in range(1,n+1):
    for j in range(1,m+1):
        if a[i][j] == 1:
##            ans[i][j] = 9
            print(9,end = " ")
        else:
            temp = [a[i-1][j-1],a[i-1][j],a[i-1][j+1],a[i][j-1],a[i][j+1],a[i+1][j-1],a[i+1][j],a[i+1][j+1]]
##            ans[i][j] = sum(temp)
            print(sum(temp),end = " ")
    print()

感想&小结:

  • 题目变水了
  • 谢谢操作系统实验课让我自己动手实现了python的面向对象编程
  • 下次求二维数组的和还是直接先切出来例如
a = [[i for i in range(6)]for _ in range(6)]
sub_a = [a[k][1:4] for k in range(1,4)]
sum_sub_a = sum(map(sum,sub_a))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值