Title making record of group B of the 12th Blue Bridge Cup provincial competition (python)

Posted by John Canyon on Tue, 11 Jan 2022 10:01:32 +0100

Fill in the blanks

space

256*1024*1024*8/32=67108864

card

n=1 #Quantity used in card 1
x=1
while n<2021:
    x+=1
    n+=str(x).count("1")
if n == 2021:
    print(x)
else:
    print(x-1)
#3181

straight line


This question is based on the idea of the boss and uses the two-point linear equation:
(y1-y2) * x +(x2-x1) * y +( x1 * y2 - x2 * y1)=0

The final result is the format of Ax+By+C=0. As long as the reduced A, B and C are different, they can be regarded as different lines

lt=[]
for i in range(20):
    for j in range(21):
        lt.append((i,j))
def gcd(x,y):
    if y==0:
        return x
    return gcd(y,x%y)

out=set()
for i in range(len(lt)-1):
    x1,y1=lt[i]
    for j in range(i+1,len(lt)):
        x2,y2=lt[j]
        A=y1-y2
        B=x2-x1
        C=x1*y2-x2*y1
        k=gcd(gcd(A,B),C)  #greatest common divisor
        out.add((A/k,B/k,C/k))
print(len(out)) 
#40257

Cargo placement

import math

n=2021041820210418
lt=set() #Collections are faster than lists
out=0
for i in range(1,int(math.sqrt(n))+1):
    if n%i==0:
        lt.add(i)
        lt.add(n//i)
for i in lt:
    for j in lt:
        for k in lt:
            if i*j*k ==n:
                out+=1
print(out)
#2430

route


I began to use Floyd solution and found that it would take a long time to run. Please refer to it later Boss blog I learned DP (dynamic programming).

Idea:

The lcm(x,y) function returns the least common multiple of X and y
The shortest distance is stored in the list out. For example, out[i] is the shortest distance from node 1 to node I. When I is in the range of [1,22], out[i]=i
But from i=23, there are out[i]=min(out[i-1]+lcm(i-1,i),out[i-2]+lcm(i-2,i),... out[i-20]+lcm(i-20,i),out[i-21]+lcm(i-21,i))
And so on until out[2021]

out = [0]*2022

def gcd(x,y): #greatest common divisor
    if y==0:
        return x
    return gcd(y,x%y)
def lcm(x,y): #Least common multiple
    g=gcd(x,y)
    return x*y//g

for i in range(1,2022):
    d = 21 #interval
    if i < 23:
        out[i] = i
    else:
        out[i] = out[i-d] + lcm(i-d,i) 
        while d:
            if out[i-d]+lcm(i-d,i) < out[i]:
                out[i] = out[i-d] + lcm(i-d,i)
            d -= 1   

print(out[2021])

Programming

Time display


n=input()
x=int(n[:-3])%(3600*24)
h,d=divmod(x,3600)
m,s=divmod(d,60)

print("{}:{}:{}".format(str(h).zfill(2),str(m).zfill(2),str(s).zfill(2)))

Weight weighing



My initial idea was to assign a coefficient k to each weight mass. The value of k is one of [1,0, - 1]. Each mass multiplied by the coefficient k is placed on the same side to see how many possibilities there are, but it's too cumbersome

After looking at the ideas of the leaders, it is found that this problem can also be DP. The idea is to define a two-dimensional array f[i][j], I is the number of weights and j is the total weight. If I weights can be used to weigh J, then f[i][j]=1. Each time a new weight (weight x) is added, there are:

f[i][x] = 1
 At the same time, if used i-1 A weight can weigh j,Then use i A weight can also weigh j,Namely f[i][j] = f[i-1][j]
On the basis of the existing combination, put a new weight on the left and right of the balance, i.e f[i][j+x]=1,f[i][abs(j-x)]=1

Finally, count the number of 1 in f[n-1], and the last two test points have timed out

n=int(input())

count=0
_max = 0 #Maximum weight that can be weighed
a=list(map(int,input().split())) #Mass of each weight stored
for i in a:
    _max += i
    
f = [[0]*2*_max for i in range(n+1)] #Array for dp
f[0][a[0]] = 1 #The value of f[i][j] is 1, which means that the mass j can be weighed with I weights

for i in range(1,n):
    x = a[i] #Mass of weight currently added
    f[i][x] = 1
    for j in range(1,_max+1):
        if f[i-1][j]:
            f[i][j] = f[i-1][j] #i-1 weight can weigh the mass, and i weight can also weigh the mass
    for j in range(1,_max+1):
        if f[i-1][j]: #Place new weights on the basis of the previous state
            f[i][j+x]=1
            f[i][abs(j-x)]=1
            
#Statistics
for i in range(1,_max+1):
    if f[n-1][i]:
        count += 1
print(count)

Yang Hui triangle



I always write overtime, refer to y God blog Yes, the boss's idea is really strong

n=int(input())

def c(a,b):
    res = 1
    i = a
    for j in range(1,b+1):
        res = res * i / j
        if res > n:
            return res
        i -= 1
    return res
def check(k):
    l = 2 * k
    r = max(n,l)
    while l<r:
        mid = l + r >>1
        if c(mid,k) >= n:
            r = mid
        else:
            l = mid +1

    if c(r,k) != n:
        return False
    print(int(r*(r+1)/2+k+1))
    return True

for i in range(16,0,-1):
    if check(i):
        break

Bracket sequence


DP can be used. The legal bracket sequence needs to meet two conditions:

1. The number of left and right brackets is the same
2. The number of left parentheses in any prefix shall not be less than the number of right parentheses

Combined with these two conditions, you can first use count to indicate how many left parentheses are more than right parentheses, and traverse the parenthesis sequence. When the left parenthesis is encountered, count+=1, otherwise count-=1. When count < 0 does not meet the second condition, an open parenthesis needs to be added, and count+=1. Finally, the value of count is the number of right parentheses to be added.

Then define the two-dimensional array f[i][j] as the number of schemes with j more left parentheses than right parentheses in the first I parentheses Therefore, f[i][j]=f[i-1][j+1]+f[i][j-1]

Specific ideas y God blog

Topics: Python