Blue Bridge Cup Day 24 (Python) (Day 7 of Crazy Questions)

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

Question type:

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)

6. "Cargo Placement" real exercise (removal of duplication, decomposition of large numbers, factorization)

7. Path (Floyd algorithm)

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 exercises​Edit

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)

Guess you like

Origin blog.csdn.net/weixin_52261094/article/details/129966085