Blue Bridge Cup Day 20 (Python) (Day 3 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:

brush questions

1. Factorial approximation (large number decomposition, cycle)

2. The number of prime factors (decomposition of large numbers, prime numbers, approximate numbers)

3. Arithmetic series (gcd function usage)

4. Fast power (Fast_pow, bit operation, shift operation)

5. Largest least common multiple (greedy, enumeration discussion)

6. Decomposition of prime factors (decomposition of large numbers, string processing functions)

7. Paper cutter (thinking questions, use of built-in functions)

8. Snake-shaped filling in numbers (thinking, observation rules)

9. Maximum rainfall (thinking questions)

10. Sorting (lexicographic order)

11. Smart monkey (minimum spanning tree, and check set)

12. Path (floyd or dijstra implementation)

13. Business trip (shortest path, matrix implements Dijstra algorithm)

14. Blue Bridge Kingdom (Dijstra algorithm template question)

15. Blue Bridge Park (Floyd algorithm template question)

brush questions

1. Factorial approximation (large number decomposition, cycle)

import sys  #设置递归深度
import collections  #队列
import itertools  # 排列组合
import heapq  #小顶堆
import math
sys.setrecursionlimit(300000)


#写法一
save=[0]*101  # 大数分解
for i in range(1,101):
   for j in range(2,int(math.sqrt(i))+1):  # 质数从2开始
      while i%j==0:  # 质数分解
         save[j]+=1
         i=i//j
   if i>1:   # 剩下的数是一个质数或者本身就是一个质数 例如10=2*5  17=1*17
      save[i]+=1

ans=1
for i in save:
   ans*=(i+1)
print(ans)

# 写法二
##MAXN = 110  
##cnt = [0] * MAXN   #记录对应质数幂次
## 
##for i in range(1, 101):
##    x = i
##    # 质因子分解
##    j = 2
##    while j * j <= x:
##        if x % j == 0:  # 是一个质数约数
##            while x % j == 0:  #类似埃式筛
##                x //= j
##                cnt[j] += 1
##        j += 1
##    if x > 1:
##        cnt[x] += 1
## 
##ans = 1
##for i in range(1, 101):
##    if cnt[i] != 0:
##        ans *= (cnt[i] + 1)  # 0 也是一种选择
## 
##print(ans)
      

 Two ways to do it, because it's 100! , so you need to traverse 1-100 to decompose large numbers. Note that prime numbers start from 2. 1 is not a prime number. You only need to traverse 2 - int( sqrt(n) ) interval to see if there is a factor of n. Python cannot get the last one So adding 1 does not mean that it is a prime number. At the same time, if it is greater than 1 after decomposition, it means that it has not been decomposed, and the rest is a prime number, such as 10. If it is not a prime number, it will become 1, such as 4,9

2. The number of prime factors (decomposition of large numbers, prime numbers, approximate numbers)

 

import sys  #设置递归深度
import collections  #队列
import itertools  # 排列组合
import heapq  #小顶堆
import math
sys.setrecursionlimit(300000)


#对一个数进行大数分解
ans=0
n=int(input())
for i in range(2,int(math.sqrt(n))+1):
   if n%i==0:  #发现质数
      ans+=1
      #print(i)  # 打印质数约数
      while n%i==0:  # 消除这个质数
         n=n//i
if n>1:
   #print(n)  # 打印质数约数
   ans+=1
print(ans)

Send sub-questions. After meeting the first question, this question will give the answer in seconds. You only need to decompose this number. You only need to ask how many prime numbers there are. Pay attention to judging if the remaining number is greater than 1 after the decomposition, it means that there are still left If a prime number is found, the answer needs to be increased by 1.

3. Arithmetic series (gcd function usage)

import sys  #设置递归深度
import collections  #队列
import itertools  # 排列组合
import heapq  #小顶堆
import math
sys.setrecursionlimit(300000)


# gcd(0,a)=a

n=int(input())
A=list(map(int,input().split()))
d=0
for i in range(len(A)-1):
   d=math.gcd(d,A[i+1]-A[i])
   #print(d) #打印d

# 需要处理d==0的情况
if d==0:
   print(n)
else:
   ans=(max(A)-min(A))//d+1
   print(ans)

Send sub-questions, but you need to carefully judge the situation. I have missed the situation when d==0 before. I didn’t consider it carefully, and there was a ÷0 error. You need to pay attention to gcd (0, a) = a , when the length is uncertain, the boundary range When using an example to determine.

4. Fast power (Fast_pow, bit operation, shift operation)

import sys  #设置递归深度
import collections  #队列
import itertools  # 排列组合
import heapq  #小顶堆
import math
sys.setrecursionlimit(300000)


b,p,q = map(int,input().split())
ans=1
while p:  # 8次方  转为二进制 1000
   if p&1: #当前位有1
      ans=ans%q * b
   b=b*b%q
   p=p>>1  # 右移即/2
print(ans%q)
   

It is a sub-question, you need to master bit operations, left shift multiplied by 2 and right remove 2, when using the while statement to loop, pay attention to changing the value at the end, such as adding left and subtracting right, shifting right and shifting left, to prevent an infinite loop.

5. Largest least common multiple (greedy, enumeration discussion)

import sys  #设置递归深度
import collections  #队列
import itertools  # 排列组合
import heapq  #小顶堆
import math
sys.setrecursionlimit(300000)


n=int(input())
# 第一时间想到 n*(n-1)*(n-2)
# 当n为奇数  最大值 n*(n-1)*(n-2)
# 当n为偶数  n和n-2可以约分
# n*(n-1)*(n-3)   (不能被3整除)
# (n-1)*(n-2)*(n-3) (能被3整除)

if n%2==1:
   print(n*(n-1)*(n-2))
else:
   if n%3==0:  #能被3整除
      print((n-1)*(n-2)*(n-3))
   else:
      print(n*(n-1)*(n-3))

 To enumerate all the cases, first take the three maximum values ​​according to the greedy idea, and then discuss the special cases, such as those with divisors, and find the coprime ones. For finding the maximum value of the least common multiple.

6. Decomposition of prime factors (decomposition of large numbers, string processing functions)

import sys  #设置递归深度
import collections  #队列
import itertools  # 排列组合
import heapq  #小顶堆
import math
sys.setrecursionlimit(300000)



a,b=map(int,input().split())
for i in range(a,b+1):
   save=i
   ans=[]  # 保存分解的数
   for j in range(2,int(math.sqrt(i))+1):
      if i%j==0:
         while i%j==0:
            ans.append(str(j))
            i=i//j
   if i >1:  # 剩下的质数或者本身是质数没有分解,例如15,5,7
      ans.append(str(i))
   print(str(save)+'='+'*'.join(ans))  # " ".join(list)  list里面的元素需要为字符类型

      
            

 Traverse these numbers and decompose each number. The difficulty lies in knowing that if the n value > 1 after decomposition, it means that there is a prime number left after the decomposition or the prime number itself cannot be decomposed into other prime numbers, and then the string splicing operation, join The () function needs to connect the elements as strings.

7. Paper cutter (thinking questions, use of built-in functions)

 There is no difficulty, it belongs to giving points, you need to understand the meaning of the question, there are only two ways of scoring, use the built-in function min() to get the minimum value, and you will get points! !

8. Snake-shaped filling in numbers (thinking, observation rules)

 What is looking for is the elements on the diagonal. Observe the law of the elements on the diagonal, that is, +4 +8 +12. If you find the law, just put a loop on it.

9. Maximum rainfall (thinking questions)

 34 ---------> 49-15=34, the above hand made a mistake

 Thinking questions, pay attention to the key points, that is, the two medians, give examples when you are uncertain, and use special examples to prove the conclusion.

10. Sorting (lexicographic order)

 Understand the meaning of lexicographic order, that is, 'a'>'b', 'a'>'ab', 'ab'>'b'. This question requires the shortest and lexicographic order, so the answer is fixed, and you need to understand the full arrangement, that is, N*(N-1)/2, that is, bca is arranged into abc full arrangement 3*2/2=3

11. Smart monkey (minimum spanning tree, and check set)

import sys  #设置递归深度
import collections  #队列
import itertools  # 排列组合
import heapq  #小顶堆
import math
sys.setrecursionlimit(300000)


def find(x):
   if x==f[x]:
      return f[x]
   else:
      f[x]=find(f[x])
      return f[x]
   
def merge(x,y):
   if find(x)!=find(y):  # 需要合根,默认合向y
      f[find(x)]=find(y)  # x的根指向y的根
         

m=int(input()) # 猴子树
leng=list(map(int,input().split()))  # 存储跳跃距离


n=int(input()) # 边数
dis = [0] # 存储坐标
for i in range(n):  
   dis.append(list(map(int,input().split())))
   
edge=[] #存储边
for i in range(1,n+1):
   for j in range(i+1,n+1):
      w=math.sqrt((dis[i][0]-dis[j][0])**2+(dis[i][1]-dis[j][1])**2) #计算距离
      edge.append((i,j,w))   # 添加边,总共添加n*(n-1)/2条边
edge.sort(key=lambda x:x[2])  # 边从小到大排序

Max=0
num=0  # 当前处理了多少条边
f=[ i for i in range(n+1)]
for i in edge:
   if find(i[0]) !=find(i[1]):   # 最小生成树算法处理
      merge(i[0],i[1])
      Max=max(Max,i[2])   #在遍历过程中记录下最长边
      num+=1

   if num==(n-1):  # 已经构建好了最小生成树
      break

ans=0  # 记录能跳的猴子数量
for i in leng:
   if i>=Max:
      ans+=1

print(ans)



 Familiar with the use of union search , the construction method of the minimum spanning tree, learn to use the Kruskal Algorithm algorithm through union search , that is, sort the edges from large to small, and traverse the shortest side to construct the minimum spanning tree method to construct the minimum spanning tree.

12. Path (floyd or dijstra implementation)

import sys  #设置递归深度
import collections  #队列
import itertools  # 排列组合
import heapq  #小顶堆
import math
sys.setrecursionlimit(300000)


# 初始化边         
dp=[[2**100]*2030 for i in range(2030)]


def lcm(a,b):
   return a//math.gcd(a,b)*b
# 赋初值
for i in range(1,2022):
   for j in range(i+1,i+22):  # 取不到最后一位
      if j>2021:
         break
      dp[i][j]=lcm(i,j)

# floyd 算距离
for k in range(1,2022):
   for i in range(1,2):
      for j in range(1,2022):
         dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])

print(dp[1][2021])
      

The floyd algorithm is many-to-many, but the time complexity is the third-order polynomial complexity, and the Dijstra complexity is lower. It is 1 to many, and the floyd algorithm can be converted to 1 to many, many to many, and many to 1 . The difficulty of this question lies in the mastery of the floyd algorithm. At the same time, it should be noted that floyd is implemented through a matrix. 

import sys  #设置递归深度
import collections  #队列
import itertools  # 排列组合
import heapq  #小顶堆
import math
sys.setrecursionlimit(300000)


# Dijstr实现
def lcm(a,b):
   return a//math.gcd(a,b)*b
def dij(s):
   done=[0]*2022  # 标记是否处理过
   hp=[]
   dis[s]=0  # 自身到自身的距离为0
   heapq.heappush(hp,(0,s))  # 入堆
   while hp:
      u=heapq.heappop(hp)[1]  # 出堆元素结点,边最小
      if done[u]==0: # 没有被处理过
         done[u]=1
         #for i in dp[u]:  # 遍历u的邻居  i:(v,w)
         for i in range(len(dp[u])):  # 遍历u的邻居  i:(v,w)
            v,w=dp[u][i]
            if done[v]==0: # 没有被处理过
               dis[v]=min(dis[v],dis[u]+w)
               heapq.heappush(hp,(dis[v],v))
            
dp=[[] for i in range(2022)]  # 邻接表
dis=[2**100] * 2022  # 初始
# 邻接表更新
for i in range(1,2022):
   for j in range(i+1,i+22):
      if j>2021:
         break
      dp[i].append((j,lcm(i,j))) # 邻居和边长

s=1  # 开始起点
dij(s)
print(dis[2021])

      

13. Business trip (shortest path, matrix implements Dijstra algorithm)

 

import sys  #设置递归深度
import collections  #队列
import itertools  # 排列组合
import heapq  #小顶堆
import math
sys.setrecursionlimit(300000)



def dij():
   dist[1]=0  #很重要
   for _ in range(n-1): # 还有n-1个点没有遍历
      t=-1
      for j in range(1,n+1):
         if st[j]==0 and (t==-1 or dist[t]>dist[j]):  #找到没处理过得最小距离点
            t=j
      for j in range(1,n+1):
         dist[j]=min(dist[j],dist[t]+gra[t][j])  # t-j的距离,找最小值
      st[t]=1  # 标记处理过
   return dist[n]
      
n,m=map(int,input().split())
 #下标全部转为从1开始
stay=[0]+list(map(int,input().split()))
stay[n]=0   
gra = [[float('inf')] * (n+1) for _ in range(n+1)]
dist = [float('inf')] * (n+1)
st=[0]*(n+1)  # 标志是否处理


for i in range(m):
   u,v,w=map(int,input().split()) #这里重构图
   gra[u][v]=stay[v]+w
   gra[v][u]=stay[u]+w


print(dij())
   

The difficulty of this question is to rebuild the map, that is, to update the time spent in each city into the map. At the same time, the DIjstra algorithm is also very important.

Template: (adjacency list)

Realized by heapq, the adjacent connection table stores (v, w) , and uses the small top heap to store. Each time the heap is released, the vertex with the minimum distance from the initial distance is obtained , and then it is judged whether its adjacent nodes have been processed. If not, these adjacent nodes are updated. Distance, and then put the calculated distance into the pile, there must be a marker matrix, a distance matrix, and an adjacency list

template: (matrix)

The edge information is stored through the matrix , and the remaining points are processed in n-1 cycles to find the point that has not been processed and is the shortest from the initial point , and then update the distance value of other points from the initial point through it to find the minimum value. Requires a label matrix, a distance matrix, and a matrix to store edges.

 Bellman-ford algorithm

n,m=map(int,input().split())
t=[0]+list(map(int,input().split()))
e=[]  #简单的数组存边

for i in range(1,m+1):
    a,b,c = map(int,input().split())
    e.append([a,b,c])  # 双向边
    e.append([b,a,c])

dist=[2**50]*(n+1)
dist[1]=0

for k in range(1,n+1): # 遍历每个点,n个点,执行n轮问路
    for a,b,c in e:  # 检查每条边,每一轮问路,检查所有边
        res=t[b]
        if b==n:
            res=0
        dist[b]=min(dist[b],dist[a]+c+res)  # 更新路径长度

print(dist[n])

14. Blue Bridge Kingdom (Dijstra algorithm template question)

 

import heapq  # 导入堆
def dij(s):
    done=[0 for i in range(n+1)]  # 记录是否处理过
    hp=[]  #堆
    dis[s]=0
    heapq.heappush(hp,(0,s))   #入堆,小顶堆
    while hp:
        u=heapq.heappop(hp)[1] #出堆元素结点
        if done[u]: #当前结点处理过
            continue
        done[u]=1
        for i in range(len(G[u])): #遍历当前结点的邻居
            v,w =G[u][i]
            if done[v]:continue
            dis[v]=min(dis[v],dis[u]+w)  # 更新当前结点邻居的最短路径
            heapq.heappush(hp,(dis[v],v))
 
 
 
 
n,m = map(int,input().split())#
s=1  # 从1开始访问
G=[[]for i in range(n+1)]   #邻接表存储
inf = 2**50
dis = [inf]*(n+1) #存储距离
for i in range(m):# 存边,这里是单向边
    u,v,w = map(int,input().split())
    G[u].append((v,w))  #记录结点u的邻居和边长
 
dij(s)
for i in range(1,n+1):
    if dis[i]==inf:
        print("-1",end=' ')
    else:
        print(dis[i],end=' ')

Template questions need to be mastered and kept in mind. This is realized through the heapq small top heap. Mastering the template is enough

15. Blue Bridge Park (Floyd algorithm template question)

import os
import sys
 
# 请在此输入您的代码
#floyd算法,多对多
 
 
def floyd():
  global dp
  for i in range(1,n+1):
    for j in range(1,n+1):
      for k in range(1,n+1):
        dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])
 
n,m,q = map(int,input().split())
inf=2**120
dp=[[inf]*(n+1) for i in range(n+1)]
choice=[]
for i in range(m):
  u,v,w=map(int,input().split())
  dp[u][v]=w
  dp[v][u]=w
for i in range(q):
  s,d = map(int,input().split())
  choice.append((s,d))
floyd()
for s,d in choice:
  if dp[s][d]!=inf:
    print(dp[s][d])
    continue
  print(-1)
   

Floyd algorithm template questions, just master it well, floyd is used for many-to-many!

Guess you like

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