十三界蓝桥杯青少年Python中组省赛试题(部分)详解

梁老师
梁老师 北京小升初老师~

0 人点赞了该文章 · 80 浏览





图片

    这不是组合问题,而是路径问题,一般用树来计算,树的叶子总数就是方法数。根节点是N,分-1,-2,-3三叉,到0为叶节点,统计数加1,小于0作废。

    程序代码(文本附录1):

图片

  运行结果:

图片

图片

  这是在矩阵中统计连通图问题,可以转化为森林统计树木数量的问题。找到一个非0点,把它变为0,然后检查上下左右是不是非0,如果是重复操作,直到上下左右都是0,统计数加1;剩下的继续检查,直到没有非0点。

  程序代码(文本附录2):

图片

图片

  运行结果:

图片


图片

  这是一道数学题,用数学语言描述:在N×M的只含有0和1的矩阵中,寻找最大边长的方阵,这个方阵只有一条对角线上的数全是1。

  数学分析:首先检查必要条件——总和等于边长数,然后再检查两条对角线;后面的检查只需检查边长数比原来大的。

  程序代码(递归,文本附录3):

图片

图片

  程序代码(循环,文本附录4):

图片

图片

  运行结果:

图片


十二界蓝桥杯Python组省赛试题详解——选择题

十二界蓝桥杯青少年Python中级组省赛试题详解——编程题之一

十二界蓝桥杯青少年Python中级组省赛试题详解——编程题之二:排序

十二界蓝桥杯青少年Python中级组省赛试题详解——编程题之三:密室逃脱

十二界蓝桥杯青少年Python中级组省赛试题详解——编程题之四/八皇后问题

十一界蓝桥杯青少年Python中/高级组省赛试题详解——选择题

十一界蓝桥杯青少年Python中/高级组省赛试题详解——编程题1~3

十一界蓝桥杯青少年Python中/高级组省赛试题详解——编程题4密码表/5节气表/6最近距离

十界蓝桥杯青少年Python中/高级组省赛试题详解——编程题1~4

十界蓝桥杯青少年Python中/高级组省赛试题详解——编程题:树形绘制


  学思营编程课堂基于蓝桥STEM86平台https://www.stem86.com,开展学编程三部曲:

Scratch(三年级以前)>>>Python(四年级以后)>>>C++(七年级以后)教育实验活动,任何人可以免费参加,打开https://xuesiying.stem86.com网页注册进入课堂,也可关注本公众号留言。

更多课程请打开“学思营”同步网站:

http://www.5xstar.com/doc.html


附录1:

N=int(input())  #输入一个正整数
c = 0 #声明方法统计数
def count(n):  #统计递归方法
    global c  #声明全局变量
    if n < 0:  #作废
        return
    elif n == 0:  #一叶节点,统计数加1,返回
        c += 1
        return
    for i in range(1,4): #每次减1到3个
        count(n-i)  #递归调用
count(N)  #执行统计
print(c)  #打印结果

附录2:

N,M = eval("["+input()+"]")  #输入矩阵行列数
lst = [ eval("["+input()+"]") for i in range(N)]  #输入矩阵
c = 0  #连通图数量
def fd(i,j,isR):  #递归统计
    '''@i行@j列@isR是否非递归调用(入口调用)'''
    global c  #声明全局变量
    if lst[i][j] > 0:  #找到一个非0点
        lst[i][j] = 0  #把这点变0
        if isR:  #如果是入口调用,连通图数量加1
            c += 1
        if i > 0:  #向上走
            fd(i-1,j,False)
        if i < N - 1:  #向下走
            fd(i+1,j,False)
        if j > 0:  #向左走
            fd(i,j-1,False)
        if j < M -1:  #向右走
            fd(i,j+1,False)
for i in range(N):  #遍历矩阵
    for j in range(M):
        fd(i,j,True)
print(c)  #打印结果

附录3:

N,M = [ int(d) for d in input().split(" ")]  #输入矩阵行列数
lst = [[int(d) for d in input().split(" ")] for i in range(N)]  #输入矩阵
c = 0  #最大奖品数
def square(i,j):  #递归方阵统计
    global c  #声明全局变量
    if i+c >= N or j+c >= M:  #越界检查
        return
    s = sum([sum(lst[k][j:j+c+1]) for k in range(i,i+c+1)])  #统计方阵1的总数
    if s!= c+1:  #如果总数不等于边长
        return
    for k in range(0,c+1):  #检查正向对角线
        if lst[i+k][j+k] == 0:
            break
    else:  #如果正向对角线全1
        c += 1  #最大奖品数加1
        square(i,j)  #递归调用
        return  #返回,不执行后续语句
    for p in range(c,-1,-1): #检查负向对角线
        if lst[i+p][j-p] == 0:
            break
    else:
        c += 1
        square(i,j)
for i in range(N):  #遍历矩阵
    for j in range(M):
        square(i,j)  #递归调用
print(c)  #打印结果

附录4:

N,M=[int(i) for i in input().split(" ")]   #输入矩阵行列数
list1=[[int(j) for j in input().split(" ")] for i in range(N)]  #输入矩阵
maxCountOne=0 #最大奖品数
for BC in range(1,min([N,M])+1):  #遍历边长可能值
    BCbreak=False  #当前边长是否终止内循环
    for j in range(N-BC+1):  #遍历当前边长方阵
        for i in range(M-BC+1):
            countOne=0  #元素1统计
            list_1=[]  #当前边长方阵收集器
            for l in range(BC):  #逐列复制方阵
                list_1.append(list1[j+l][i:i+BC])
                countOne+=sum(list_1[l])  #统计1列
            if countOne==BC:  #统计值符合必要条件——等于边长
                for k in range(BC):
                    if list_1[k][k] == 0:
                        break
                else:   #如果正向对角线全1
                    maxCountOne,BCbreak=BC,True  #最大奖品数等于边长,终止当前边长检查
                    break  #中断行循环
                for k in range(BC):  #检查正向对角线
                    if list_1[k][BC-k-1] == 0:
                        break
                else:
                    maxCountOne,BCbreak=BC,True
                    break
        if BCbreak:  #中断列循环,进入下一个边长数的循环
            break
print(maxCountOne)  #打印结果

图片


添加 家长论坛微信 



发布于 2024-04-26 20:23

免责声明:

本文由 梁老师 原创发布于 家长帮 ,著作权归作者所有。

登录一下,更多精彩内容等你发现,贡献精彩回答,参与评论互动

登录! 还没有账号?去注册

暂无评论

广告
All Rights Reserved Powered BY WeCenter V4.1.0 © 2025 京ICP备20005761号-2