1.卡片

1.1原题

蓝桥杯备战日志(Python)1-卡片&直线(普通填空)_浮点数


1.2分析

      题意抽象:现有10种数字卡片0~9,每种卡片有2021个,使用这些数字组成新的数字1,2,3,4,...,n,即从1开始,每次加1,直到所需卡片数量不足。在现有的20210个数字卡片下,n的最大值为多少?

由题意可知,在不断拼新的数时,数字1是最先使用的数字,且一定是使用最多的数字,因为在拼一位数时,首先使用数字卡片1,到最小的两位数10之前,其它数字卡片的消耗量不会超过数字卡片1的;接着,在拼两位数时,也不难发现,数字卡片1的消耗量始终不低于其它9种数字卡片,使用数字卡片拼更多位数的整数时情况同上。

综上可知,数字卡片1一定会被最先消耗完,所以,当拼新的数字m时,且发现卡片1的数量已经不够时,m-1就是我们要找的n的最大值。


1.3源码

one_sum = 2021  # 数字卡片1的数量
m = 1 # 当前需要拼的数字
while True:
# 使用卡片拼数字m,统计消耗卡片1的数量并从总数中扣减
one_sum -= str(m).count('1')
# 卡片1数量不足,退出
if one_sum < 0:
n = m-1
break
# 继续拼新的数字
m += 1

print(n)


2.直线

2.1原题

蓝桥杯备战日志(Python)1-卡片&直线(普通填空)_斜率_02

2.2分析

      这题思路不难,但是个易错题。设横坐标和纵坐标的个数分别为m,n(这里m=20, n=21)。

① 首先考虑斜率不存在的直线,即使直线上的任意两点的横坐标相同,共m条。

② 若直线斜率存在,设直线上的任意两点的坐标分别为(x1, y1)和(x2, y2),直线的斜率和截距分别为k和b,遍历坐标的每种可能性,计算出不同直线的数量(即斜率k和截距b不全相等)。这里的一个易错点是,编程时不能直接用b = y1-k*x1求出截距b,这是因为k的结果是浮点数,计算的精度是有损失的,并且损失的精度会因点的坐标的不同而不同,斜率和截距应该使用坐标的值表示,如下图

蓝桥杯备战日志(Python)1-卡片&直线(普通填空)_斜率_03


2.3源码

m = 20
n = 21

kb_s = set() # 存放直线斜率和截距的集合,集合中的元素为一个元组(k,b)
res = m # 斜率不存在的情况

# 遍历坐标的每种可能性
for x1 in range(m):
for y1 in range(n):
for x2 in range(m):
for y2 in range(n):
if x1==x2:
continue
# 求斜率和截距
k = (y1-y2)/(x1-x2)
b = (x1*y2-x2*y1)/(x1-x2)
kb_s.add((k,b))

res += len(kb_s)
print(res)