【预览】蓝桥杯竞赛python算法笔记 代码模板|吐血总结|蓝桥杯省赛国赛

【预览】蓝桥杯竞赛python算法笔记 代码模板|吐血总结

完整版链接

文章目录

1 二分算法求分界值

想看到完整代码模板 请订阅专栏~

2 双指针算法

2.1 求最长的不包含重复数字的连续子序列

# 只会遍历整个数组一次
j=0
for i in range(n):
  while(j<=i and check(j,i)):
    j-=1
  res=max(res,i-j-1)

3 排列组合

3.1 next_permutation 重排列一个序列 生成它的上一个序列

本代码的原题是luogu的火星人

# 对于12345的序列 最多让我数到54321
def nextP(index):
  	global s
    for t in range(index):
        if(n<=1): # 如果一共的字母小于等于1 没什么要干的 返回
            return
        for i in range(n-2,-1,-1): 
          # 从后往前看 找到第一个不是降序的数x
            if(s[i]<s[i+1]): 
                for j in range(n-1,-1,-1): 
                    if(s[j]>s[i]): # 从后往前找 找到第一个大于x的数
                        s[i],s[j]=s[j],s[i] # 把它们交换
                        s[i+1:]=sorted(s[i+1:]) # 后面按照升序排序
                        break 
                break
            else:
                if(i==0): s.sort()
n=int(input())
index=int(input())
s=[int(i) for i in input().split()]

nextP(index)
print(' '.join(map(str,s)))
# 没有括号的版本
def nextP(index):
	global s
	for t in range(index):
		for i in range(n-2,-1,-1):
			if s[i]<s[i+1]:
				for j in range(n-1,-1,-1):
					if s[j]>s[i]:
						s[i],s[j]=s[j],s[i]
						s[i+1:]=sorted(s[i+1:])
						break
				break
			else:
				if i==0:
					s.sort()
n=int(input())
index=int(input())
s=[int(i) for i in input().split()]

if n>1:
	nextP(index)
print(" ".join(map(str,s)))

3.3 n个数字/字母的不同排列

# n个数字的不同排列
from itertools import permutations
n=int(input())
s=[i for i in input().split()]
for p in permutations(s):
  print("".join(map(str,p)))

# n个字母的不同排列
str=list(input().split()) # 根据空格划分开
for p in permutations(str):
  print("".join(p))

3.4 n个数字选k个数的组合

想看到完整代码模板 请订阅专栏~

3.5 在n个数字中选1~n个数的不同组合

3.5.1 自己写dfs的方法

想看到完整代码模板 请订阅专栏~

4 组合数计算

组合数用这个公式来计算:

C a b = C a − 1 b + C a − 1 b − 1 C_a^b=C_{a-1}^b+C_{a-1}^{b-1} Cab=Ca1b+Ca1b1 表示从a个苹果选择b个苹果 可以把选法(不重合不漏)分为2大类

  1. 包含此苹果 C a − 1 b − 1 C_{a-1}^{b-1} Ca1b1
  2. 不包含此苹果 C a − 1 b C_{a-1}^b Ca1b

想看到完整代码模板 请订阅专栏~

5 快速幂

利用 a 2 0 , a 2 1 . . . a 2 l o g ( k ) a^{2^0},a^{2^1}...a^{2^{log(k)}} a20,a21...a2log(k)快速计算出幂(二进制的思想)

def qpow(a,k,mod):
    res=1
    while(k):
        if(k&1): # 这里是取最后一位数
            res=res*a%mod
        k>>=1 # 右移一位
        a=a*a%mod # 把乘积翻倍
    return res

n=int(input())
for k in range(n):
    a,k,p=map(int,input().split())
    print(qpow(a,k,p))

6 求质数

6.1 试除法

6.2 朴素筛法

# 朴素筛法
N=1000010
n=int(input())
st=[0 for i in range(N)] # 记录是否是质数 0表示是质数
primes[0 for i in range(N)]
cnt=0

def get_primes(n): # 找出1-n的所有质数并存在primes[]数组中
  global cnt,primes
  for i in range(2,n+1):
    if(st[i]==0): # i是质数
      primes[cnt]=i
      cnt+=1
      for j in range(i+i,n+1,i):
        st[j]=1

get_primes(n)
print(cnt)

6.3 线性筛质数-只用最小质因子来筛

想看到完整代码模板 请订阅专栏~

7 约数和约数有关

7.1 输出所有的约数

想看到完整代码模板 请订阅专栏~

7.2 约数的个数

想看到完整代码模板 请订阅专栏~

7.3 质因子分解

想看到完整代码模板 请订阅专栏~

8 欧几里得算法

8.1 欧几里得

# 简单的最大公约数
def gcd(a,b):
    if b==0: return a
    return gcd(b,a%b)

8.2 最小公倍数

最小公倍数=两整数的乘积/最大公约数

想看到完整代码模板 请订阅专栏~

9 图和树有关

9.1 建图方法

# 建立邻接表
N=100010
e=[0 for i in range(N)] # 存放的是各边的到达结点的号
ne=[0 for i in range(N)] # next指针数组 存放的邻接表的下一个节点的位置
h=[-1 for i in range(N)] # 头指针数组 指向这个结点的相邻结点(存放头结点在e中的index)
w=[0 for i in range(N)] # 边的权值
# dis数组存的是到达对应index结点的最短距离
idx=0

def add(a,b,c):
  global idx,e,ne,h,w
  e[idx]=b
  w[idx]=c
  ne[idx]=h[a]
  h[a]=idx
  idx+=1

# 访问某一个点的邻边的时候
t=h[a]
while(t!=-1):
  node=e[t] # 一定要去e[t]才是真的点 不然只是一个下标
  # 对这个node进行一波操作
  t=ne[t]

9.2 最短路算法

9.2.1 单源最短路-dijkstra

dijkstra算法必须规定起点

(1)朴素dijkstra

不常用 背诵下面优化的dijkstra比较好

# 朴素 使用邻接矩阵存
N=510
g=[[float('inf') for i in range(N)] for j in range(N)]
st=[False for i in range(N)]
dist=[float('inf') for i in range(N)]

def dijkstra(start,end): # 从点start走到点end的路径
  global dist,st,g
  dist[start]=0
  for i in range(n): # 遍历从start开始的n个点
    t=-1
    for j in range(1,n+1):
      if(st[j]==False and (t==-1 or dist[t]>dist[j])): # t==-1 表示是遇到的第一个点 dist[t]>dist[j]表示要更新当前路径最短的点
        t=j
      if(t==end): # 最短路已经更新到了end
        break # 如果要寻找到所有点的最短路不知道还要不要break
      st[t]=True
      
     想看到完整代码模板 请订阅专栏~

(2)堆优化dijkstra

想看到完整代码模板 请订阅专栏~

9.2.2 多源汇最短路-SPFA算法

SPFA是bellman-ford的改进版

SPFA算法可以算出从起点到任何点的最短路

想看到完整代码模板 请订阅专栏~

9.3 最小生成树算法

最小生成树算法在无向图上使用,背下来kruskal就可以了

9.3.1 kruskal最小生成树

想看到完整代码模板 请订阅专栏~

9.3.2 prim最小生成树

不常用 一般用kruskal

想看到完整代码模板 请订阅专栏~

9.3.3 拓扑排序

想看到完整代码模板 请订阅专栏~

10 差分算法

想看到完整代码模板 请订阅专栏~

11 并查集

# 并查集find函数
def find(x):  
    if(x!=p[x]):  p[x]=find(p[x])  
    return p[x]
# 并查集union函数
for i in range(m):  
    a,b=map(int,input().split())  
    pa,pb=find(a),find(b)  
    if(pa!=pb): p[pa]=pb # 注意这里的操作!!

12 DFS和BFS

12.1 DFS

  1. 内部搜索(棋盘的结点作为结点)
  2. 外部搜索(棋盘的状态作为结点)
# dfs基本框架
def dfs():
    

12.2 BFS-和最短路有关的问题

# bfs基本框架
queue=[]
queue.append([sx,sy]) # 初始结点入队
while(queue):  
    front=queue.pop(0)  
    ...

bfs最经典的是最短步数问题,每次向各个方向走一步的时候就step+1

13 DP背包模版(重点)

13.1 01背包

(1)二维/基本的01背包

想看到完整代码模板 请订阅专栏~

(2)一维的01背包

想看到完整代码模板 请订阅专栏~

13.2 完全背包

(1)朴素完全背包

想看到完整代码模板 请订阅专栏~

(2)优化的二维完全背包

想看到完整代码模板 请订阅专栏~

(3)优化的一维完全背包

想看到完整代码模板 请订阅专栏~

13.3 多重背包

(1)朴素的多重背包

想看到完整代码模板 请订阅专栏~

(2)二进制优化的多重背包

想看到完整代码模板 请订阅专栏~

13.4 分组背包-类似多重背包

想看到完整代码模板 请订阅专栏~

14 DP数字三角形

从下到上更新
n=int(input())
f=[]
for i in range(n):
    f.append([int(i) for i in input().split()])

for i in range(n-2,-1,-1): # 从n-2(倒数第二行)到0行
  for j in range(i+1): # 列内按从左到右 一列的数字个数是i+1个
    f[i][j]+=max(f[i+1][j],f[i+1][j+1]) # 左下和右下较大
print(f[0][0])
从上到下更新

想看到完整代码模板 请订阅专栏~

15 DP的LCS模版

最长上升子序列

想看到完整代码模板 请订阅专栏~

最长公共子序列

想看到完整代码模板 请订阅专栏~

最长公共上升子序列

想看到完整代码模板 请订阅专栏~

16 记忆化搜索

摘花生
# 摘花生dp做法
T=int(input())
for t in range(T):
  n,m=map(int,input().split())
  f=[[] for j in range(110)]
  f[0]=[0 for i in range(m+1)]
  for i in range(1,n+1):
    f[i]=[0]+[int(i) for i in input().split()]
  for i in range(1,n+1):
    for j in range(1,m+1):
      f[i][j]+=max(f[i-1][j],f[i][j-1])
  print(f[n][m])
# 摘花生记忆化搜索
def dfs(x,y):
  global res,cur
  dx=[1,0]
  dy=[0,1]
  cur+=f[x][y]
  if(x==n and y==m):
    res=max(res,cur)
    return
  for i in range(2):
    xx=x+dx[i]
    yy=y+dy[i]
    if(xx<1 or yy<1 or xx>=n or yy>=m): continue
    dfs(xx,yy)
  cur-=f[x][y]

T=int(input())
res=0
cur=0
for t in range(T):
  n,m=map(int,input().split())
  f=[[] for j in range(110)]
  f[0]=[0 for i in range(m+1)]
  for i in range(1,n+1):
    f[i]=[0]+[int(i) for i in input().split()]
dfs()  
print(res)
  • 19
    点赞
  • 151
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

妮妮学姐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值