Question type:
1. Thinking questions/Miscellaneous questions: Mathematical formulas, analyzing the meaning of questions, finding patterns
2. BFS/DFS: wide search (recursive implementation), deep search (deque implementation)
3. Simple number theory: modulus, prime number (only need to judge to int (sqrt (n)) + 1), gcd, lcm, fast exponentiation (bit operation shift operation), large number decomposition (decomposition into the product of prime numbers)
4. Simple graph theory: shortest path (one-to-many (Dijstra, adjacent table, matrix implementation), many-to-many (Floyd, matrix implementation)), minimum spanning tree (and search set implementation)
5. Simple string processing: it is best to switch to list operations
6. DP: Linear DP, longest common subsequence, 0/1 knapsack problem, longest continuous string, largest increasing substring
7. Basic algorithms: binary, greedy, combination, permutation, prefix sum, difference
8. Basic data structures: queues, sets, dictionaries, strings, lists, stacks, trees
9. Commonly used modules: math, datetime, set the maximum recursion depth in sys (sys.setrecursionlimit(3000000)), collections.deque (queue), itertools.combinations (list, n) (combination), itertools.permutations (list, n) (permutation) heapq (small top heap)
Table of contents
Brushing questions: 1. "GCD" real test practice (thinking, mathematical properties, gcd)
2. "Frogger Crossing the River" real test practice (two points, mathematical thinking)
3. "Sum of Squares of Factors" practice questions (Number Theory)
4. "Cards" exercise (thinking)
5. "Straight line" exercise (spatial line, set)
8. "Circuit Counting" practice exercises (dp)
9. "Time Display" real exercise (formatted output)
10. "Yang Hui Triangle" real test exercise (2 points, just cheat points for difficult problems)
11. "Left Child Right Brother" real exercise (dfs, tree)
12. "Exclusive OR Sequence" exercise (difficult, don't take this score)
13. "Bracket Sequence" real test practice (only need to score violently)
14. House number production (string operation)
15. "Looking for 2020" real test exercise (violent cycle string operation)
16. "Running Exercise" real exercise (use of datetime library)
17. "Snake-shaped Number Filling" practice exercises (rules of thinking)
18. "Sorting" real exercise (full arrangement, find the rules)
19. "Adornment Beads" practice exercisesEdit
20. "Score Statistics" practice test (selection)
21. "Word Analysis" practice exercises (built-in functions, max, min)
22. "Numerical Triangle" exercise (violent cycle)
23. "Plane Segmentation" real exercise (find the law)
Brushing questions:
1. "GCD" real test practice (thinking, mathematical properties, gcd)
Preliminary idea: enumerate k violently, so I feel that I can't pass all the data, and the title requires finding the minimum k value.
Look for the rules to see if there are any rules?(wrong, only 2 test points passed)
import sys #设置递归深度
import collections #队列
import itertools # 排列组合
import heapq #小顶堆
import math
sys.setrecursionlimit(300000)
import functools # 自定义比较函数 -1不变,1交换
'''
12 23 34 45 56 67 0
13 35 57 79 (2 1)
14 47 25 36 (3 2)
15 59 (4 1)
16 5 10 (5 4)
# 规律,相差为质数,就是质数-1 即d-1
'''
def is_prime(x):
for i in range(2,int(math.sqrt(x))+1):
if x%2==0:
return False
else:
return True
a,b=map(int,input().split())
if is_prime(abs(b-a)):
print(abs(a-b)-1)
else:
print(0)
Positive solution: nature: gcd (a, b) = gcd (ab, b)
gcd(a+k,b+k)=gcd(a+k,ba)≤min(a+k,ba), let gcd=ba directly to ensure the maximum gcd
Standard schedule:
a, b = map(int, input().split())
r = a % (b - a)
if r == 0:
print(0)
else:
print(b - a - r)
2. "Frogger Crossing the River" real test practice (two points, mathematical thinking)
Preliminary idea: do it through deep search DFS, a mark array, maintain the number of stones, (number, position)
Positive solution: The answer has monotonicity, the minimum jumping distance is 1, and the maximum is n, and the solution is solved by dichotomizing the answer.
Standard schedule:
n, x = list(map(int, input().split()))
H = [0, *list(map(int, input().split()))] #下标从1开始
Pre_Sum = [0] * (n)
for idx in range(1, n): #预处理前缀和
Pre_Sum[idx] = Pre_Sum[idx - 1] + H[idx]
#判定能力为y时,是否合法
def check(y):
#枚举所有长度为y的区间
for l in range(1, n - y + 1):
r = l + y - 1
if Pre_Sum[r] - Pre_Sum[l - 1] < 2 * x:
return False
return True
#二分答案
l, r = 1, n
ans = -1
while l <= r:
mid = (l + r) // 2
if check(mid):
ans = mid
r = mid - 1
else:
l = mid + 1
print(ans)
3. "Sum of Squares of Factors" practice questions (Number Theory)
Preliminary Thoughts: Cycle of Violence
Positive solution: Consider optimization and record the number of occurrences of each factor
Standard schedule:
MOD = 1000000007
#求数字1-n的平方和
def S(x):
return x * (x + 1) * (2 * x + 1) // 6
n = int(input())
ans = 0
l = 1
#枚举左端点
while l <= n:
r = min(n // (n // l), n)
ans += (n // l) * (S(r) - S(l - 1))
l = r + 1
print(ans % MOD)
4. "Cards" exercise (thinking)
Preliminary idea: see who uses the least, then loop, and just jump out when you are done using it
Positive answer: the same
Standard schedule:
a = [2021 for i in range(10)]
def check(x):
while(x > 0):
now = int(x % 10)
if(a[now] > 0):
a[now] -= 1
else:
return 0
x = x // 10
return 1
cnt = 1
while(check(cnt)):
cnt += 1
print(cnt - 1)
5. "Straight line" exercise (spatial line, set)
Preliminary idea: through the set to replay different slopes, the number of separate calculations perpendicular to the x-axis
Positive solution: the same, but pay attention to decimal precision and use sets to deduplicate
Standard schedule:
import sys #设置递归深度
import collections #队列
import itertools # 排列组合
import heapq #小顶堆
import math
sys.setrecursionlimit(300000)
import functools # 自定义比较函数 -1不变,1交换
import os
import sys
# 请在此输入您的代码
m=set()
for i in range(0,20): # 0-1
for j in range(0,21): # 0-2
for x in range(0,20):
for y in range(0,21):
if x-i!=0:
# y=kx+b
k=(y-j)/(x-i)
b=y-k*x
m.add((round(k,5),round(b,5))) # 精度问题,不保留小数会出现问题
#m.add((k,b)) # 除法保留16位小数
print(len(m)+20)
6. "Cargo Placement" real exercise (removal of duplication, decomposition of large numbers, factorization)
Preliminary thoughts: none
Positive solution: record the factors of n, and traverse the combination of factors in a 3-fold cycle. There is an optimization, that is, if the multiplication of the first two factors is greater than n, skip the next layer of cycle and pruning operation.
Decompose n prime factors through large number decomposition, and then traverse how many combinations there are through BFS, that is
(len (number of prime factors), x, y, z), use the set to deduplicate.
Standard schedule:
n = 2021041820210418
i = 1
a = []
cnt = 0
while i * i <= n:
if n % i == 0:
a.append(i)
if i != n / i:
a.append(int(n / i))
i += 1
for i in range(len(a)):
for j in range(len(a)):
if a[i] * a[j] > n:
continue
for k in range(len(a)):
if a[i] * a[j] * a[k] == n:
cnt += 1
print(cnt)
7. Path (Floyd algorithm)
Preliminary idea: Floyd's algorithm (3-fold cycle), or the algorithm of the police asking for directions (2-fold cycle).
Positive solution: Dijstra algorithm, the simplest is Floyd
Standard schedule:
import math
def lcm(a, b):
return int(a * b / math.gcd(a, b))
n = 2021
g = [[0 for i in range(1, n + 2)] for j in range(1, n + 2)]
for i in range(1, n + 1):
for j in range(1, n + 1):
if i == j:
g[i][j] = g[j][i] = 0
elif abs(i - j) <= 21:
g[i][j] = g[j][i] = lcm(i, j)
else:
g[i][j] = 1000000000
for k in range(1, n + 1):
for i in range(1, n + 1):
for j in range(1, n + 1):
if g[i][j] > g[i][k] + g[k][j]:
g[i][j] = g[i][k] + g[k][j]
print(g[1][n])
8. "Circuit Counting" practice exercises (dp)
Preliminary idea: first build a map, build a map through the adjacency list, then search through dfs, and finally return to the origin and add 1 to the count.
Positive solution: Construct the adjacency matrix through the matrix, the state DP
Standard schedule:
# python 跑的相当慢,不过这是道填空题就无所谓了
import math
dp = [[0] * (22) for i in range(2100000)]
g = [[0 for i in range(22)] for i in range(22)]
n = 1 << 21
for i in range(1, 22):
for j in range(1, 22):
if math.gcd(i, j) == 1:
g[i - 1][j - 1] = g[j - 1][i - 1] = 1
dp[1][0] = 1
i = 1
while i < n:
for j in range(0, 21):
if (i >> j & 1) == 0:
continue
for k in range(0, 21):
if g[j][k] == 0 or (i >> k & 1) != 0:
continue
dp[(i + (1 << k))][k] += dp[i][j]
i += 1
res = 0
for i in range(0, 21):
res += dp[n - 1][i]
print(res)
9. "Time Display" real exercise (formatted output)
Preliminary idea: directly take the remainder to calculate the hour, minute, and second of the day, and then perform integer division to get the hour, minute, and second
import os
import sys
# 请在此输入您的代码
n=int(input())
time=n%(1000*60*60*24)
h=time//(1000*60*60)
m=(time-h*1000*3600)//(1000*60)
s=(time-h*1000*3600-m*60*1000)//1000
print('{:0>2d}:{:0>2d}:{:0>2d}'.format(h,m,s))
Positive solution: only consider the last day, 1s=1000ms
Standard schedule:
import os
import sys
n = int(input())
n /= 1000
n %= 24 * 60 * 60
h = int(n / 3600)
m = int(n / 60) % 60
s = int(n % 60)
if h <= 9:
h = str(0) + str(h)
else :
h = str(h)
if m <= 9:
m = str(0) + str(m)
else:
m = str(m)
if s <= 9:
s = str(0) + str(s)
else:
s = str(s)
print(h + ':'+ m + ':' + s)
10. "Yang Hui Triangle" real test exercise (2 points, just cheat points for difficult problems)
Preliminary idea: first calculate the values of the previous dozens of lines, splice them into one line, and evaluate them through the index of the list
Positive solution: two branch numbers
import os
import sys
# 请在此输入您的代码
n=[0,1,1,1,1,2,1]
#n=[[0],[1,1],[1,2,1]]
last=[1,2,1]
for i in range(50):
new=[]
for a,b in zip(last+[0],[0]+last):
new.append(a+b)
n.append(new)
last=new
m=int(input())
print(n.index(m))
correct answer:
Standard schedule:
import os
import sys
n = int(input())
def C(a, b):
res = 1
i = a
j = 1
while j <= b:
res = int(res * i / j)
if res > n:
return int(res)
i -= 1
j += 1
return int(res)
for k in range(16, -1, -1):
l = 2 * k
r = max(n, l)
res = int(-1)
while l <= r:
mid = l + r >> 1
if C(mid, k) >= n:
res = mid
r = mid - 1
else:
l = mid + 1
if C(res, k) == n:
print((res + 1) * res // 2 + k + 1)
break
11. "Left Child Right Brother" real exercise (dfs, tree)
Preliminary thoughts: none
Positive solution: Store the multi-fork tree through the list, dfs search, that is, dfs(i) the highest height of the i-root binary tree
dfs(i) = number of children + max() dfs(each child))
5
1 1 [ 2 3 4 ]
1 2 [ 5 ]
1 3 [ ]
2 4 [ ]
5 [ ]
Standard schedule:
import sys #设置递归深度
import collections #队列
import itertools # 排列组合
import heapq #小顶堆
import math
sys.setrecursionlimit(300000)
import functools # 自定义比较函数 -1不变,1交换
n = int(input())
A = [[]for i in range(n+1)]
for i in range(2,n+1):
v=int(input())
A[v].append(i) # 添加子节点
def dfs(i):
if A[i] is None:
return 0
maxn = 0
for j in A[i]:
maxn = max(maxn ,dfs(j))
return len(A[i])+maxn
print(dfs(1))
12. "Exclusive OR Sequence" exercise (difficult, don't take this score)
Preliminary thoughts: none
Positive solution: knowledge of game theory
13. "Bracket Sequence" real test practice (only need to score violently)
Preliminary idea: Convert the brackets to 0,1 numbers, see how many insertion methods there are, and dfs searches from left to right?
"""
0001
010101
010011
001101
001011
000111"""
Scale (violence):
for(int i = 1 ; i <= cnt ; i ++) dp[1][i] = 1;
if(sum[1] > 0) dp[1][0] = 1;
for(int i = 2 ; i <= n ; i ++){
for(int j = i - sum[i] ; j <= cnt ; j ++){
for(int k = 0 ; k <= j ; k ++){
dp[i][j] += dp[i - 1][k];
dp[i][j] %= mod;
}
}
}
14. House number production (string operation)
string manipulation
15. "Looking for 2020" real test exercise (violent cycle string operation)
Cycles of violence will do, stats.
import sys #设置递归深度
import collections #队列
import itertools # 排列组合
import heapq #小顶堆
import math
sys.setrecursionlimit(300000)
import functools # 自定义比较函数 -1不变,1交换
import os
import sys
# 请在此输入您的代码
a="""
022220000002200200202022000202222022202222222202022002222200022200222220020200222020002022222220022202000002220020220002022222022022002022202222222000022002020002202002022000022000202200000220200022200020220222000022202222000222222022202022222022200002202220222000202000200002220200000200202002202202
"""
b=[]
a=a.split() # 300*300
for i in a:
b.append(list(i))
ans=0
#s="002000000220202000222000202200222220202202020002220002020022202200220220202002002220020200000000220022200202222022220222000022220220020020222020022220022220220000022022002020220002200220020020022200020222020200200000020220020022002202000202222020220020020022020000202022220222200022220000000020020020"
#print(len(s))
def check1(i,j):
if i+3<=299 and b[i][j]=='2' and b[i+1][j]=='0' and b[i+2][j]=='2' and b[i+3][j] =='0':
return True
else :
return False
def check2(i,j):
if j+3<=299 and b[i][j]=='2' and b[i][j+1]=='0' and b[i][j+2]=='2' and b[i][j+3] =='0':
return True
else :
return False
def check3(i,j):
if i+3<=299 and j+3<=299 and b[i][j]=='2' and b[i+1][j+1]=='0' and b[i+2][j+2]=='2' and b[i+3][j+3] =='0':
return True
else :
return False
for i in range(300):
for j in range(300):
if check1(i,j):
ans+=1
if check2(i,j):
ans+=1
if check3(i,j):
ans+=1
print(ans)
Standard schedule:
n = 300
ans = 0
s = []
for i in range(n):
t = input()
s.append(t)
for i in range(len(s)):
for j in range(len(s[i])):
if j + 3 < len(s[i]) and s[i][j] + s[i][j + 1] + s[i][j + 2] + s[i][j + 3] == '2020':
ans += 1
for i in range(len(s)):
for j in range(len(s[i])):
if i + 3 < len(s) and s[i][j] + s[i + 1][j] + s[i + 2][j] + s[i + 3][j] == '2020':
ans += 1
for i in range(len(s)):
for j in range(len(s[i])):
if i + 3 < len(s) and j + 3 < len(s[i]) and s[i][j] + s[i + 1][j + 1] + s[i + 2][j + 2] + s[i + 3][j + 3] == '2020':
ans += 1
print(ans)
16. "Running Exercise" real exercise (use of datetime library)
Send sub-questions? Use the datetime library to loop through
import sys #设置递归深度
import collections #队列
import itertools # 排列组合
import heapq #小顶堆
import math
sys.setrecursionlimit(300000)
import functools # 自定义比较函数 -1不变,1交换
import datetime # date,timedelta,isoweekday()
begin=datetime.date(2000,1,1)
end=datetime.date(2020,10,1)
delta=datetime.timedelta(1)
ans=0
while begin !=end:
if begin.day==1 or begin.isoweekday()==1: #月初或者星期一
ans+=2
else: ans+=1
begin+=delta
print(ans+2)
Standard schedule:
import os
import sys
import datetime
start = datetime.date(2000, 1, 1)
end = datetime.date(2020, 10, 1)
days = datetime.timedelta(days=1)
ans = 0
while end >= start:
if start.day == 1 or start.weekday() == 0:
ans += 2
else:
ans += 1
start += days
print(ans)
17. "Snake-shaped Number Filling" practice exercises (rules of thinking)
find regular questions
18. "Sorting" real exercise (full arrangement, find the rules)
19. "Decorative Beads" exercise
Preliminary idea: I can’t understand the meaning of the question, so skip it
20. "Score Statistics" practice test (selection)
Choose to judge and send sub-questions
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)))
21. "Word Analysis" practice exercises (built-in functions, max, min)
Send points, use the built-in function to find the maximum and minimum
import os
import sys
s = input()
ma = 0
ch = 'z'
for j in s:
cnt = s.count(j)
if cnt >= ma:
ma = cnt
for j in s:
if s.count(j) == ma:
ch = min(ch , j)
print(ch)
print(ma)
22. "Numerical Triangle" exercise (violent cycle)
Preliminary idea: Traverse from top to bottom, because the difference between the number of times to go down to the left and the number of times to go down to the right cannot exceed 1, and the final end point must be the middle position.
import os
import sys
dp = []
n = int(input())
for i in range(n):
dp.append(list(map(int, input().split())))
for i in range(n):
for j in range(i + 1):
if i == 0:
dp[i][j] = dp[i][j]
elif j == 0:
dp[i][j] = dp[i - 1][j] + dp[i][j]
elif j == i:
dp[i][j] = dp[i - 1][j - 1] + dp[i][j]
else:
dp[i][j] = max(dp[i - 1][j - 1],dp[i - 1][j]) + dp[i][j]
if n % 2 == 0:
print(max(dp[n - 1][n // 2 - 1],dp[n - 1][n // 2]))
else:
print(dp[n - 1][n // 2])
23. "Plane Segmentation" real exercise (find the law)
Preliminary idea: draw a picture to find the law
Positive solution: add n intersection points, add n+1 planes, pay attention to deduplication, deduplication of intersection points and lines.
Standard schedule:
import os
import sys
n = int(input())
line = set()
node = set()
ans = 1
def calc(a , b):
node.clear()
for j in line:
A = j[0]
B = j[1]
if A == a:
continue
x = 1.0 * (B - b) / (a - A)
y = x * a + b
node.add((x , y));
return len(node) + 1
for i in range(n):
a, b = list(map(int, input().split()))
if (a, b) in line:
continue
ans += calc(a , b)
line.add((a, b))
print(ans)