第15届蓝桥杯省赛python组A,B,C集合

        过几天就省赛了,一直以来用的是C++,Python蓝桥杯也是刚刚开始准备(虽然深度学习用的都是python,但是两者基本没有任何关系),这两天在做去年题时犯了很多低级错误,因此记录一下以便自己复查

PS:很多问题的实现其实都是基于C++换成python的,因此很多代码显得比较丑,还请见谅。

为了结构清晰,我从Python易错点和2024年题目这两部分进行展开:

2024真题(大部分写了,但有一小部分没有做):

1.树状数组+思维:6000. 植物生命力 - AcWing题库

思路:

我们反过去考虑,一个点的贡献不就是当前链上的比他大的又不是它的倍数的点的个数吗?这个链怎么保证呢?DFS递归序列不就是一条链吗,因此这点可以通过DFS实现,那怎么查到比他大的数又不是整除的呢?不妨先考虑比他大的,我们在DFS过程中维护树状数组即可,我们再通过枚举它的倍数对整除的进行排除即可。

代码实现:

import sys

from types import GeneratorType
def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc


n,s=map(int,input().split())
a=list(map(int,input().split()))
a=[0]+a
edge=[[] for i in range(n+10)]
tr=[0 for i in range(200010)]
vis=[0 for i in range(200010)]
ans=0
def lowbit(x):
    return x&-x

def add(pos,v):
    while pos<=n:
        tr[pos]+=v
        pos=pos+lowbit(pos)

def get(pos):
    res=0
    while pos>0:
        res+=tr[pos]
        pos-=lowbit(pos)
    
    return res
    
@bootstrap
def dfs(root,fa):
    global ans
    global n
    
    res=get(n)-get(a[root])
    
    for i in range(2*a[root],n+1,a[root]):
        if vis[i]==1:
            res-=1
    ans+=res
    vis[a[root]]=1
    add(a[root],1)
    for i in edge[root]:
        if i==fa:
            continue
        yield dfs(i,root)
    vis[a[root]]=0
    add(a[root],-1)
    yield None

for _ in range(n-1):
    u,v=map(int,input().split())
    edge[u].append(v)
    edge[v].append(u)

dfs(s,-1)
print(ans)

2.trie树链路减法:5999. 最大异或结点 - AcWing题库

思路:如果不管那个不能异或相连的点的话就是一个很板的字典树问题,现在我们的问题就是如何解决这个相连点不能异或的限制。

比较直观的想法就是把那个节点相邻的点从字典树中删除,然后正常操作,最后再恢复,那么如何实现呢?比较巧妙地,我们再新开一个数组来记下树上每个点的出现次数,删除的话就是依次从树链中走下来,走到的节点位置次数-1即可。

代码实现:

import sys
from types import GeneratorType
def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc
ans = 0
ind = 1
n = int(input())
N = 32
### 关于蓝桥杯第十五 Python B 的相关题目与解析 对于蓝桥杯第十五 Python B 的比,其主要涉及的内容涵盖了算法设计、编程技巧以及逻辑推理等多个方面。以下是针对这一事的一些具体分析和解答。 #### 题目概述 比中的题目通常分为多个难度等级,从简单的计算到复杂的算法实现都有所覆盖。例如,在引用[2]中提到的一道题目涉及到 **并查集** 的应用,这是一种用于处理动态连通性的高效数据结构[^2]。通过将符合条件的城市分至同一集合,最终可以快速统计每内的连接关系数目 \( n \times (n - 1) \),其中 \( n \) 表示当前集合中的城市数量。 #### 并查集的应用实例 下面是一个基于并查集的经典实现代码,适用于解决类似的图论问题: ```python class UnionFind: def __init__(self, size): self.parent = list(range(size)) def find(self, x): if self.parent[x] != x: self.parent[x] = self.find(self.parent[x]) return self.parent[x] def union(self, x, y): rootX = self.find(x) rootY = self.find(y) if rootX != rootY: self.parent[rootY] = rootX def count_connections(cities, roads): uf = UnionFind(cities) for a, b in roads: uf.union(a, b) group_sizes = {} for city in range(cities): root = uf.find(city) group_sizes[root] = group_sizes.get(root, 0) + 1 total = 0 for size in group_sizes.values(): total += size * (size - 1) return total ``` 上述代码展示了如何利用并查集来管理城市的分情况,并进一步计算各内部可能形成的路径总数。 #### 数据范围的重要性 在竞环境中,合理评估给定的数据规模至关重要。如果能够提前预判某些特定方法的时间复杂度是否会超出允许范围,则有助于选择更优的解决方案。正如引用[2]所示,“这题看到数据范围”,便迅速联想到适用的算法策略——即采用并查集而非暴力枚举的方式解决问题。 #### 总结 综上所述,参加像蓝桥杯这样的程序设计大不仅考验选手的基础知识掌握程度,还对其灵活运用各种技术手段的能力提出了较高要求。通过对实际案例的学习研究,参者可以获得宝贵经验以应对未来挑战。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值