试题A:卡片
思路: 因为1是最先用的,故1肯定也是最先用完的,当1用完时,即1出现的次数大于2021时,说明此时的数不能被拼出来,设为x,则最大能拼出的数为x-1。在统计当前数1的出现次数时,可用到str(x).count('1'),将该数转为字符串后,统计字符'1'的出现次数即可。代码如下:
sum = 0
i = 1
while True:
sum += str(i).count("1")
if sum > 2021:
print(i-1)
break
i += 1
试题B:直线
看了大佬的wp才知道得用点基础的数学知识:
斜率k = (y2 - y1) / (x2 - x1) 截距b = y1 - k*x1 = (x2*y1 - x1*y2) / (x2 - x1)
用set创建一个无序不重复元素集t(有效的避免了纵坐标相同的点只会形成一条直线的情况),依次将每条边的斜率和截距作为一个元素存入t中,最后看t中有多少个元素,再加上20即可(因为有竖着的20条边,在计算斜率时分母为0,在存入直线信息时,遇到横坐标相同的直接跳过),代码如下:
#斜率k = (y2 - y1) / (x2 - x1)
#截距b = y1 - k*x1 = (x2*y1 - x1*y2) / (x2 - x1)
m = []
t = set()#无序不重复元素集
for i in range(20):
for j in range(21):
m.append([i,j])#得到点集合
for i in m:
x1,y1 = i[0],i[1]
for j in m:
x2,y2 = j[0],j[1]
if x2 == x1:
continue
k = (y2 - y1) / (x2 - x1)
b = (x2 * y1 - x1 * y2) / (x2 - x1)
if (k,b) not in t:
t.add((k,b))
print(len(t)+20)