Lanqiao Cup 2020 Provincial Competition Python
Question 1: House plate production
An algorithm with a time complexity of n is used. Anyway, there will be no TLE for filling in the blanks, as long as it is not too outrageous.
Using python’s count function
res = 0
for i in range(1,2021):
i = str(i)
res += i.count('2')
print(res)
The answer is 2
Question 2: Looking for 2020
Just search row by column, first traverse each row, and then traverse each column. In this way, for the i-th row, as long as j+4 <= the total number of columns, you can traverse [i][j],[i][j] of the matrix. +1]…[i][j+3], see if he is equal to 2020
For columns, as long as the current number of rows i + 3 < the total number of rows, it can be traversed as above, just change the rows and columns
Diagonally the same, as long as i + 3 < total number of rows, j + 3 < total number of columns
PS: j + 3 < total number of columns is the same as j+4 <= total number of columns, but j+4 will be used below for the first one, so I will write j+4
nums = [[2, 2, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 2, 2, 0, 2],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 2, 2],
[0, 0, 2, 0, 2, 0],
]
res = 0
for i in range(len(nums)): # 行
for j in range(len(nums[0])): # 列
if j + 4 <= len(nums[0]): # 超出了
a = nums[i][j:j+4]
if a == [2,0,2,0]:
res += 1
if i+3 < len(nums):
b = nums[i][j]*1000 + nums[i+1][j] * 100 + nums[i+2][j] *10 + nums[i+3][j]
if b == 2020:
res += 1
if i+3 < len(nums) and j+3 < len(nums[0]):
c = nums[i][j] * 1000 + nums[i+1][j+1] * 100 +nums[i+2][j+2] * 10 + nums[i+3][j+3]
if c ==2020:
res += 1
print(res)
Question 3: Running exercise
Just judge, if it is Monday or the beginning of the month, add + 2, otherwise add 1. There is no need to consider the simultaneous situation here, because if it is Monday or the beginning of the month, we will continue directly and only add 2 once. Python has a special The datetime library can solve this problem
import datetime
a = datetime.date(2000,1,1)
b = datetime.date(2020,10,2)
res = 0
while True:
if a == b: break
if a.day == 1:
res += 2
a = a + datetime.timedelta(days = 1)
continue
if a.isoweekday() == 1:
res += 2
a = a+datetime.timedelta(days = 1)
continue
res += 1
a = a + datetime.timedelta(days = 1)
print(res)
4. Snake-shaped fill-in number
Just fill it in, if i is an even number, fill in j from 0 to i-1, otherwise it will be reversed
lst = [[] for _ in range(40)]
lst[0].append(1)
num=1
for i in range(2,40):
if i % 2 == 0:
for j in range(i):
num += 1
lst[j].append(num)
else:
for j in range(i):
num += 1
lst[i - j -1].append(num)
for i in range(len(lst)):
print(i + 1, lst[i])
print(lst[19][19])
PS I took a look, I guess it’s okay to find the rules directly
5. Sort
This requires an understanding of the principle of bubble sorting. First of all, if n numbers are all sorted backwards, there are a total of n-1 + n-2 + n-3 ... + 1 secondary exchange order
And because he wants the shortest English sequence, we first sort it in reverse order. When there are 15 English letters in reverse order, a total of 105 exchanges are required. If the lexicographic order is small, then o...a.
Then, because the dictionary order is small, we try to put the smallest one first, and at the same time, it can be exchanged 100 times, then put j in the front, so that the first five words will be exchanged with j less once, so the answer is
print('jonmlkihgfedcba')
Question 6: Score statistics
This question is relatively simple so I won’t explain it further.
if __name__ == '__main__':
n = int(input())
jige = 0
youxiu = 0
for i in range(n):
m = int(input())
if m >= 85:
youxiu += 1
jige += 1
elif m >= 60:
jige += 1
print('{:.0f}%'.format((jige/n)*100))
print('{:.0f}%'.format((youxiu/n)*100))
Question 7: Word Analysis
At first I felt that I should use the count function to do it, but then I thought about it and it was a bit troublesome to sort it into dictionary order. We put it in collections to do it. The defaultdict(int) inside can be used for counting, and then converted into dictionary
import collections
s = input()
dic = collections.defaultdict(int) # 参数输int就可以计数
for i in s:
dic[i] += 1
dic = dict(dic.items())
dic = sorted(dic.items(),key= lambda x:x[0], reverse=False) # 先按字典序排 升序,排完就变成一个列表了
dic = sorted(dic, key = lambda x:x[1],reverse=True) # 再按大小排,这样就都排好了 降序
print(dic[0][0])
print(dic[0][1])
Question 8: Digital Triangle
When I first read it, I thought it was the most basic number triangle. After writing it, I found that the answer was wrong. Mine was 30 and his was 27. I read the question again and found that the difference between the number of times to the left and the number of right turns cannot exceed 1. .
Then I stupidly wrote another one. The number of left or right turns to reach each vertex cannot exceed 1. I found that it was still wrong, because this limited the whole. He only requires that when the last line is reached, the difference between the number of times the path goes left and right cannot exceed 1
After a final push, if n is an odd number, then if he wants to get to the last row and the number of times the path goes left or right cannot exceed 1, he can only reach the middle one. If n is an even number, then he can only reach the middle two (this method is passed, I tried it to prove that there is no problem)
# 如果符合要求的话 n 为奇数只有最后一行的中间点符合 偶数只有中间两个点符合
if __name__ == '__main__':
n = int(input())
f,a = [[-1]*(n+1) for _ in range(n+1)],[[0] for _ in range(N)]
for i in range(1,n+1):
a[i] += [int(x) for x in input().split()]
f[1][1] = a[1][1]
for i in range(2,n+1): # 第i行
for j in range(1,i+1): # 第j列
f[i][j] = max(f[i-1][j] + a[i][j], f[i-1][j-1] + a[i][j])
if n % 2 == 0:
res = max(f[n][n//2],f[n][n//2+1])
else:
res = f[n][n//2+1]
print(res)
Question 9: Plane Segmentation
I have done this question on pythontip before, so it doesn’t feel difficult to do it. Just look for the pattern. If the line added later has n different intersections with the previous line, then he will add n+1 more. flat
n = int(input())
lines = []
for i in range(n):
a, b = map(int, input().split())
lines.append((a, b))
lines = list(set(lines)) # 去重
def cross(line1,line2): # 求交点
A1,B1,A2,B2 = line1[0],line1[1],line2[0],line2[1]
if A1 - A2 == 0: return # 返回NONE
x = (B2 - B1) / (A1 - A2)
y = A1 * x + B1
x = round(x, 10)
y = round(y, 10)
return (x, y)
ci = [1] *(n+1) # 第i条直接加入对答案的贡献,下标从0开始,默认那个1就已经加上了
node = set()
for i in range(1,n): # 从第二条线开始
node.clear()
for j in range(i):
tmp = cross(lines[i],lines[j])
if tmp == None: continue
node.add(tmp)
ci[i] += len(node)
print(sum(ci[:n])+1) # 加上最开始其实是有两个平面,我们只算了一个
Question 10: Decorative beads
Well, the last question is still very interesting. For this kind of question, I usually just need to be able to do it, regardless of TLE. . So I used a method that was considered violent.
In fact, he doesn't care what the six pieces of equipment look like. He only cares about the total number of holes and levels, the levels of all beads, and their value. So let's first store the number of holes and levels of all equipment,
lv[i] represents the number of items with level i
limit[i] indicates how many beads of grade i can be placed in the end
value[i][j] indicates the value of j beads with grade i
lv = [0]*5 # 表示等级为i的孔的数量
limit = [0]*5
value = [[0] for i in range(5)]
for i in range(6):
a = list(map(int,input().split()))
for i in range(1,len(a)):
lv[a[i]] += 1 #等级为i的物品+1
m = int(input())
for i in range(m):
zhu = list(map(int,input().split()))
limit[zhu[0]] = zhu[1] # limit[i] 表示等级为i的珠子最多镶嵌多少个
value[zhu[0]] += zhu[2:] # value[i][j] 表示等级为i的珠子用了j个的价值
Well, now that everything is saved, we start to traverse all the possibilities,
Just traverse the beads with level 4 and put i beads, and put j beads with level 3. It should be noted that the beads with level 4 can put at most min(limit[4],lv[4]), that is, it cannot exceed The restriction for level 4 beads is the same as the number of slots for level 4 equipment. The same is true for level 3 beads, except that it can be placed in level 4 and level 3 equipment slots.
res = 0
# 对每个珠子的等级进行枚举
for i in range(min(lv[4],limit[4])+1): # 等级为4的选i个
for j in range(min(lv[3] + lv[4] - i,limit[3])+1): # 等级为3的珠子能放进3和4的孔中
for k in range(min(lv[4] + lv[3] + lv[2] -i -j,limit[2])+1):
for l in range(min(lv[4] + lv[3] + lv[2] + lv[1] -i -j -k,limit[1])+1):
res = max(res,value[4][i] + value[3][j] + value[2][k] + value[1][l])
print(res)
The complete code is as follows
lv = [0]*5 # 表示等级为i的孔的数量
limit = [0]*5
value = [[0] for i in range(5)]
# print(summ)
for i in range(6):
a = list(map(int,input().split()))
for i in range(1,len(a)):
lv[a[i]] += 1 #等级为i的物品+1
m = int(input())
for i in range(m):
zhu = list(map(int,input().split()))
limit[zhu[0]] = zhu[1] # limit[i] 表示等级为i的珠子最多镶嵌多少个
value[zhu[0]] += zhu[2:] # value[i][j] 表示等级为i的珠子用了j个的价值
res = 0
# 对每个珠子的等级进行枚举
for i in range(min(lv[4],limit[4])+1): # 等级为4的选i个
for j in range(min(lv[3] + lv[4] - i,limit[3])+1): # 等级为3的珠子能放进3和4的孔中
for k in range(min(lv[4] + lv[3] + lv[2] -i -j,limit[2])+1):
for l in range(min(lv[4] + lv[3] + lv[2] + lv[1] -i -j -k,limit[1])+1):
res = max(res,value[4][i] + value[3][j] + value[2][k] + value[1][l])
print(res)