蓝桥杯备赛[day02]3月16日|python|复习回顾|背诵枚举模版
Posted alwaysuzybaiyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯备赛[day02]3月16日|python|复习回顾|背诵枚举模版相关的知识,希望对你有一定的参考价值。
目录
复习回顾
1 成绩统计
用cnt1表示及格的人数,cnt2表示优秀的人数,答案即为cnt1/n、cnt2/n四舍五入后乘100!
不要忘记输出百分号!
import os
import sys
# 请在此输入您的代码
n = int(input())
cnt1 = 0
cnt2 = 0
for i in range(1,n+1):
x = int(input())
if x >= 60:
cnt1 += 1
if x >= 85:
cnt2 += 1
print(":.0f%".format(round(100.0 * cnt1 / n,2)))
print(":.0f%".format(round(100.0 * cnt2 / n,2)))
5
0
100
60
85
70
80%
40%
2 排列字母
直接对字符串进行排序即可,使用标准排序函数。
Python先转换成 list 再进行排序,最后拼接成字符串(因为 Python 中无法修改字符串元素)。
import os
import sys
# 请在此输入您的代码
s = 'WHERETHEREISAWILLTHEREISAWAY'
s = list(s)
s.sort()
print("".join(s))
out=AAAEEEEEEHHHIIILLRRRSSTTWWWY
⚠️join函数前面是 .
3 纸张尺寸
根据题意维护长边长度a和短边长度b。
对于输入A0而言,a=1189, b=841。 根据输入的A后面的数字x,循环x次:
每次让长边a除以2(向下取整),短边b不变。
然后再根据a,b的大小关系进行调整,如果a<b则交换a,b。
短边变成长边,长边的一半变为短边。
1 枚举题
题目需要处理大量同类情况
暴力枚举所有情况 (枚举是暴力的一种)
利用计算机强大的算力
注意:不要遗漏任何情况
注意:如果枚举量太大,需要剪枝
1.1 枚举的思想
将问题的所有可能成为答案的解一一列举,然后根据问题所给出的条件判断此解是否合适,如果合适就保留,反之则舍弃。
1.2 枚举解题的要素
确定枚举解的范围,以及判断条件
选取合适枚举方法,进行逐一枚举,此时应注意能否覆盖所有的可能的解
在枚举时使用判断条件检验,留下所有符合要求的解。
1.3 枚举的步骤
1.根据题目确定枚举的范围,并选取合适的枚举方式,不能遗漏任何一个真正解,同时避免重复。
2.为了提高解决问题的效率,看题目是否存在优化,将可能成为解的答案范围尽可能缩小。
3.根据问题找到合理、准确描述、易编码的验证条件。
4.枚举并判断是否符合第3步确定的的条件,并保存符合条件的解。
5.按要求输出枚举过程中留下的符合条件的解。
1.3.1 例题
蓝桥杯题库613
一个整数如果只含有因子3、5、7,称为幸运数字。 前10个幸运数字是3、5、7、9、15、21、25、27、35、45。 问59084709587505 是第几个幸运数字。
【题目描述】一个整数如果只含有因子3、5、7,称为幸运数字。问59084709587505是第几个幸运数字。
【解题思路】暴力枚举。这个系列的数可以表示为3^i × 5^j × 7^k,枚举所有不超过范围的i、j、k组合。代码中最小的3^50肯定超过59084709587505。
import numpy as np
cnt=0
for i in range(50):
for j in range(50):
for k in range(50):
a = 3**i
b = 5**j
c = 7**k
if a*b*c <=59084709587505:
cnt += 1
print(cnt-1)
#out=1906-1=1905; 1不是幸运数字!
2 枚举技术
把所有情况排列、组合出来,逐个处理。
2.1 组合型枚举
确认n和m的数量后,我们可以直接套模版,输出结果。
import numpy as np
chosen = []
n = 0
m = 0
def calc(x):
if len(chosen) > m:
return
if len(chosen) + n - x + 1 < m:
return
if x == n + 1:
for i in chosen:
print(i,end=' ')
print(' ')
return
calc(x + 1)
chosen.pop()
if __name__ == '__main__':
tem = input().split()
n = int(tem[0])
m = int(tem[1])
calc(1)
2.2 排列型枚举
全排列
order = [0] * 20
chosen = [0] * 20
n = 0
def calc(x):
if x == n + 1:
ansTem = ''
for i in range(1, n + 1):
print(order[i],end=' ')
print('')
return
for i in range(1,n+1):
if(chosen[i]==1):
continue
order[x]=i
chosen[i]=1
calc(x+1)
chosen[i]=0
order[x]=0
if __name__ == '__main__':
n = int(input())
calc(1)
Python排列函数permutations():
功能:连续返回由 iterable序列中的元素生成的长度为r的排列。
如果r未指定或为None,r默认设置为 iterable 的长度,即生成包含所有元素的全排列。
from itertools import*
s = ['a','b','c']
for element in permutations(s,2):
a = element[0] + element[1]
#或者这样写:
a = ".join(element)
print(a)
3 二进制法
(2023年 4月6日 22:55首次发布)
蓝桥杯备赛--教你用矩阵优化递推
先导知识
- 矩阵乘法
[ a b c d ] ∗ [ e f g h ] = [ a e + b g a f + b h c e + d g c f + d h ] \\beginbmatrix a & b \\\\ c & d \\endbmatrix * \\beginbmatrix e & f \\\\ g & h \\endbmatrix = \\beginbmatrix ae+bg & af+bh \\\\ ce+dg & cf+dh \\endbmatrix [acbd]∗[egfh]=[ae+bgce+dgaf+bhcf+dh]
由此可见矩阵乘法不满足交换律! - 单位矩阵(矩阵对角线为1,其余都为0,常用E表示)
[ 1 0 0 . . . 0 0 1 0 . . . 0 0 0 1 . . . 0 . . . . . . . . . 0 0 0 0 1 ] \\beginbmatrix 1 & 0 & 0 & ... & 0 \\\\ 0 & 1 & 0 &... & 0 \\\\ 0 & 0 & 1 & ... & 0\\\\ & ... & ... & ...\\\\ 0 & 0 & 0 & 0 &1 \\endbmatrix ⎣⎢⎢⎢⎢⎡1000010...0001...0............00001⎦⎥⎥⎥⎥⎤
单位矩阵在矩阵世界里相当于常数中的1,任何矩阵乘单位矩阵都等于该矩阵本身
OK, 接下来进入正题
如何用矩阵优化递推
举例子永远是最好理解新知识的方法。
斐波那契数列,不懂得可以百度一下。主要是说一个数列,前两项为1,从第3项开始数列的值为前两项之和。
用函数表示为:
F
i
b
(
n
)
=
1
n<=2
F
i
b
(
n
−
1
)
+
F
i
b
(
n
−
2
)
n > 2
Fib(n) = \\begincases 1 &\\textn<=2 \\\\ Fib(n-1)+Fib(n-2)&\\textn > 2 \\endcases
Fib(n)=1Fib(n−1)+Fib(n−2)n<=2n > 2
有了递推公式,相信求出斐波那契数列的第n项是多少,用递推很好求出来。但是当n大于
1
0
18
10^18
1018时,递推就会超时。
所以接下来介绍另一种求法。
我们从递推公式可以看出,当
n
<
=
2
n<=2
n<=2的时候,
F
i
b
(
1
)
=
F
i
b
(
2
)
=
1
Fib(1)=Fib(2) = 1
Fib(1)=Fib(2)=1,那么就可以构造一个Base矩阵作为起始矩阵。
B
a
s
e
=
[
1
1
]
Base = \\beginbmatrix 1& 1 \\endbmatrix
Base=[11]
当
n
>
2
n>2
n>2时
F
i
b
(
n
)
Fib(n)
Fib(n) 是由
F
i
b
(
n
−
1
)
Fib(n-1)
Fib(n−1) 和
F
i
b
(
n
−
2
)
Fib(n-2)
Fib(n−2) 决定的。
那么我们就可以构造一个状态转移矩阵 T。
[
F
i
b
(
n
−
1
)
F
i
b
(
n
−
2
)
]
∗
[
1
1
]
\\beginbmatrix Fib(n-1) & Fib(n-2) \\endbmatrix * \\beginbmatrix 1\\\\ 1 \\endbmatrix
[Fib(n−1)Fib(n−2)]∗[11]
=
F
i
b
(
n
−
1
)
+
F
i
b
(
n
−
2
)
= Fib(n-1)+Fib(n-2)
=Fib(n−1)+Fib(n−2)
=
F
i
b
(
n
)
= Fib(n)
=Fib(n)
而求
F
i
b
(
n
+
1
)
Fib(n+1)
Fib(n+1)需要
F
i
b
(
n
)
Fib(n)
Fib(n)和
F
i
b
(
n
−
1
)
Fib(n-1)
Fib(n−1),所以还需要求一下
F
i
b
(
n
−
1
)
Fib(n-1)
Fib(n−1)。
[
F
i
b
(
n
−
1
)
F
i
b
(
n
−
2
)
]
∗
[
1
0
]
\\beginbmatrix Fib(n-1) & Fib(n-2) \\endbmatrix * \\beginbmatrix 1\\\\ 0 \\endbmatrix
[Fib(n−1)Fib(n−2)]∗[10]
=
F
i
b
(
n
−
1
)
= Fib(n-1)
=Fib(n−1)
所以这个 T 矩阵就是:
[
1
1
1
0
]
\\beginbmatrix 1 & 1\\\\ 1 & 0 \\endbmatrix
[1110]
至此,当你求斐波那契数列的第五项时,对应的矩阵公式就是:
B
a
s
e
∗
T
3
=
[
1
1
]
∗
[
1
1
1
0
]
3
=
[
F
i
b
(
5
)
F
i
b
(
4
)
]
Base * T^3 = \\beginbmatrix 1 & 1 \\endbmatrix * \\beginbmatrix 1 & 1\\\\ 1 & 0 \\endbmatrix ^ 3 = \\beginbmatrix Fib(5) & Fib(4) \\endbmatrix
Base∗T3=[11]∗[1110蓝桥杯备赛--带你入门树状数组