Blue Bridge Cup Tag 20 (Python) (Tag 3 der verrückten Fragen)

Fragetyp:

1. Denkfragen/Verschiedene Fragen: Mathematische Formeln, Analyse der Bedeutung von Fragen, Finden von Mustern

2. BFS/DFS: breite Suche (rekursive Implementierung), tiefe Suche (Deque-Implementierung)

3. Einfache Zahlentheorie: Modul, Primzahl (muss nur nach int (sqrt (n)) + 1 beurteilt werden), gcd, lcm, schnelle Potenzierung (Bitoperation, Verschiebungsoperation), Zerlegung großer Zahlen (Zerlegung in das Produkt einer Primzahl). Zahlen)

4. Einfache Graphentheorie: kürzester Weg (eins-zu-viele (Dijstra, benachbarte Tabelle, Matriximplementierung), viele-zu-viele (Floyd, Matriximplementierung)), minimaler Spannbaum (und Suchsatzimplementierung)

5. Einfache Zeichenfolgenverarbeitung: Wechseln Sie am besten zu Listenoperationen

6. DP: Linearer DP, längste gemeinsame Teilfolge, 0/1-Rucksackproblem, längste kontinuierliche Zeichenfolge, größte ansteigende Teilfolge

7. Grundlegende Algorithmen: binär, gierig, Kombination, Permutation, Präfixsumme, Differenz

8. Grundlegende Datenstrukturen: Warteschlangen, Mengen, Wörterbücher, Zeichenfolgen, Listen, Stapel, Bäume

9. Häufig verwendete Module: Mathematik, Datum und Uhrzeit, legen Sie die maximale Rekursionstiefe in sys fest (sys.setrecursionlimit (3000000)), Sammlungen.deque (Warteschlange), itertools.combinations (Liste, n) (Kombination), itertools.permutations (Liste). , n) (Permutation) heapq (kleiner oberer Heap)

Inhaltsverzeichnis

Fragetyp:

Pinselfragen

1. Faktorielle Näherung (Zerlegung großer Zahlen, Zyklus)

2. Die Anzahl der Primfaktoren (Zerlegung großer Zahlen, Primzahlen, Näherungszahlen)

3. Arithmetische Reihe (Verwendung der GCD-Funktion)

4. Schnelle Leistung (Fast_pow, Bitoperation, Schiebeoperation)

5. Größtes kleinstes gemeinsames Vielfaches (gierig, Aufzählungsdiskussion)

6. Zerlegung von Primfaktoren (Zerlegung großer Zahlen, String-Verarbeitungsfunktionen)

7. Papierschneider (Denkfragen, Nutzung integrierter Funktionen)

8. Schlangenförmiges Ausfüllen von Zahlen (Denken, Beobachtungsregeln)

9. Maximaler Niederschlag (Denkfragen)

10. Sortieren (lexikografische Reihenfolge)

11. Smart Monkey (minimaler Spannbaum und Prüfsatz)

12. Pfad (Floyd- oder Dijstra-Implementierung)

13. Geschäftsreise (kürzester Weg, Matrix implementiert den Dijstra-Algorithmus)

14. Blue Bridge Kingdom (Frage zur Vorlage des Dijstra-Algorithmus)

15. Blue Bridge Park (Floyd-Algorithmus-Vorlagenfrage)

Pinselfragen

1. Faktorielle Näherung (Zerlegung großer Zahlen, Zyklus)

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)
      

 Zwei Möglichkeiten, es zu tun, denn es sind 100! Sie müssen also 1-100 durchlaufen, um große Zahlen zu zerlegen. Beachten Sie, dass Primzahlen bei 2 beginnen. 1 ist keine Primzahl. Sie müssen nur das Intervall 2 - int( sqrt(n) ) durchlaufen, um zu sehen, ob es eine gibt Faktor von n. Python kann den letzten nicht erhalten. Das Hinzufügen von 1 bedeutet also nicht, dass es sich um eine Primzahl handelt. Wenn sie nach der Zerlegung größer als 1 ist, bedeutet dies gleichzeitig, dass sie nicht zerlegt wurde, der Rest jedoch eine Primzahl, zum Beispiel 10. Wenn es keine Primzahl ist, wird sie zu 1, zum Beispiel 4,9

2. Die Anzahl der Primfaktoren (Zerlegung großer Zahlen, Primzahlen, Näherungszahlen)

 

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)

Senden Sie Unterfragen. Nachdem Sie die erste Frage beantwortet haben, wird diese Frage in Sekundenschnelle die Antwort liefern. Sie müssen diese Zahl nur zerlegen. Sie müssen nur fragen, wie viele Primzahlen es gibt. Achten Sie darauf, zu beurteilen, ob die verbleibende Zahl größer ist als 1 nach der Zerlegung, bedeutet dies, dass noch übrig sind. Wenn eine Primzahl gefunden wird, muss die Antwort um 1 erhöht werden.

3. Arithmetische Reihe (Verwendung der GCD-Funktion)

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)

Senden Sie Unterfragen, aber Sie müssen die Situation sorgfältig beurteilen. Ich habe die Situation, in der d == 0 ist, schon einmal übersehen. Ich habe nicht sorgfältig darüber nachgedacht und es gab einen ÷0-Fehler. Sie müssen auf gcd achten ( 0, a) = a Wenn die Länge unsicher ist , wird der Grenzbereich anhand eines Beispiels bestimmt.

4. Schnelle Leistung (Fast_pow, Bitoperation, Schiebeoperation)

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)
   

Dies ist eine Unterfrage. Sie müssen Bitoperationen beherrschen, die Linksverschiebung mit 2 multiplizieren und die Rechtsverschiebung mit 2 multiplizieren. Wenn Sie die while-Anweisung für eine Schleife verwenden, achten Sie darauf, den Wert am Ende zu ändern, z. B. das Addieren nach links und das Subtrahieren nach rechts. Verschiebung nach rechts und Verschiebung nach links, um eine Endlosschleife zu verhindern.

5. Größtes kleinstes gemeinsames Vielfaches (gierig, Aufzählungsdiskussion)

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))

 Um alle Fälle aufzuzählen, nehmen Sie zunächst die drei Maximalwerte gemäß der gierigen Idee, diskutieren Sie dann die Sonderfälle, z. B. solche mit Teilern, und finden Sie die Koprime-Fälle. Zum Ermitteln des Maximalwerts des kleinsten gemeinsamen Vielfachen.

6. Zerlegung von Primfaktoren (Zerlegung großer Zahlen, String-Verarbeitungsfunktionen)

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里面的元素需要为字符类型

      
            

 Durchlaufen Sie diese Zahlen und zerlegen Sie jede Zahl. Die Schwierigkeit besteht darin, zu wissen, dass, wenn der n-Wert nach der Zerlegung > 1 ist, dies bedeutet, dass nach der Zerlegung noch eine Primzahl übrig ist oder dass die Primzahl selbst nicht in andere Primzahlen zerlegt werden kann Der String-Splice-Vorgang, join Die ()-Funktion muss die Elemente als Strings verbinden.

7. Papierschneider (Denkfragen, Nutzung integrierter Funktionen)

 Es gibt keine Schwierigkeiten, es gehört zum Vergeben von Punkten, Sie müssen die Bedeutung der Frage verstehen, es gibt nur zwei Möglichkeiten zur Bewertung: Verwenden Sie die integrierte Funktion min(), um den Mindestwert zu erhalten, und Sie erhalten Punkte! !

8. Schlangenförmiges Ausfüllen von Zahlen (Denken, Beobachtungsregeln)

 Gesucht werden die Elemente auf der Diagonale. Beachten Sie das Gesetz der Elemente auf der Diagonale, also +4 +8 +12. Wenn Sie das Gesetz finden, legen Sie einfach eine Schleife darauf.

9. Maximaler Niederschlag (Denkfragen)

 34 ---------> 49-15=34, die obige Hand hat einen Fehler gemacht

 Achten Sie beim Nachdenken auf die Kernpunkte, also auf die beiden Mediane, geben Sie Beispiele, wenn Sie sich nicht sicher sind, und verwenden Sie spezielle Beispiele, um die Schlussfolgerung zu beweisen.

10. Sortieren (lexikografische Reihenfolge)

 Verstehen Sie die Bedeutung der lexikografischen Reihenfolge, d. h. „a“ > „b“, „a“ > „ab“, „ab“ > „b“. Diese Frage erfordert die kürzeste und lexikografische Reihenfolge, sodass die Antwort festgelegt ist und Sie die vollständige Anordnung verstehen müssen, dh N * (N-1) / 2, dh bca wird in abc vollständige Anordnung 3 * 2 angeordnet /2=3

11. Smart Monkey (minimaler Spannbaum und Prüfsatz)

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)



 Vertraut mit der Verwendung der Union-Suche , der Konstruktionsmethode des minimalen Spannbaums, lernen Sie, den Kruskal-Algorithmus-Algorithmus durch die Union-Suche zu verwenden , dh die Kanten von groß nach klein zu sortieren und die kürzeste Seite zu durchlaufen, um den minimalen Spannbaum zu erstellen Methode zur Konstruktion des minimalen Spannbaums.

12. Pfad (Floyd- oder Dijstra-Implementierung)

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])
      

Der Floyd-Algorithmus ist viele zu viele, aber die Zeitkomplexität ist die Polynomkomplexität dritter Ordnung, und die Dijstra-Komplexität ist geringer. Sie beträgt 1 zu viele, und der Floyd-Algorithmus kann in 1 zu viele, viele zu viele umgewandelt werden , und viele zu 1 . Die Schwierigkeit dieser Frage liegt in der Beherrschung des Floyd-Algorithmus. Gleichzeitig ist zu beachten, dass Floyd durch eine Matrix implementiert wird. 

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. Geschäftsreise (kürzester Weg, Matrix implementiert den Dijstra-Algorithmus)

 

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())
   

Die Schwierigkeit dieser Frage besteht darin, die Karte neu zu erstellen, d. h. die in jeder Stadt verbrachte Zeit auf der Karte zu aktualisieren. Gleichzeitig ist auch der DIjstra-Algorithmus sehr wichtig.

Vorlage: (Adjazenzliste)

Durch Heapq realisiert, speichert die benachbarte Verbindungstabelle (v, w) und verwendet zum Speichern den kleinen oberen Heap. Jedes Mal, wenn der Heap freigegeben wird, wird der Scheitelpunkt mit dem minimalen Abstand vom Anfangsabstand erhalten , und dann wird beurteilt, ob Die angrenzenden Knoten wurden verarbeitet. Wenn nicht, werden diese benachbarten Knoten aktualisiert. Wenn Sie die Entfernung entfernen und dann die berechnete Entfernung in den Stapel legen, müssen eine Markierungsmatrix, eine Entfernungsmatrix und eine Adjazenzliste vorhanden sein

Vorlage: (Matrix)

Die Kanteninformationen werden über die Matrix gespeichert , und die verbleibenden Punkte werden in n-1 Zyklen verarbeitet, um den Punkt zu finden, der nicht verarbeitet wurde und der kürzeste vom Anfangspunkt ist , und dann den Abstandswert anderer Punkte vom Anfangspunkt zu aktualisieren Zeigen Sie hindurch, um den Mindestwert zu ermitteln. Erfordert eine Beschriftungsmatrix, eine Abstandsmatrix und eine Matrix zum Speichern von Kanten.

 Bellman-Ford-Algorithmus

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 (Frage zur Vorlage des Dijstra-Algorithmus)

 

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=' ')

Vorlagenfragen müssen beherrscht und im Auge behalten werden. Dies wird durch den kleinen oberen Heapq von Heapq erreicht. Es reicht aus, die Vorlage zu beherrschen

15. Blue Bridge Park (Floyd-Algorithmus-Vorlagenfrage)

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)
   

Fragen zur Floyd-Algorithmusvorlage, beherrschen Sie sie einfach gut, Floyd wird für viele zu viele verwendet!

Supongo que te gusta

Origin blog.csdn.net/weixin_52261094/article/details/129899614
Recomendado
Clasificación