[Notes on the Blue Bridge Cup National Championships] Python

 Blue Bridge Cup 22 days recently, I feel that the more I brush the questions, the higher the AC rate is getting better and better

Emm the following explanations are quite detailed

If you have any questions, please leave a comment

 1. Heavenly Stems and Earthly Branches (fill in the blank)

Topic description

Ancient China used the Heavenly Stems and Earthly Branches to keep track of the current year.

There are ten stems in the sky: Jia (jiǎ), B (yǐ), Cing (bǐng), Ding (dīng), Wu (wù), Ji (jǐ), Geng (gēng), Xin (xīn), Ren (rén), Gui (guǐ).

There are twelve earthly branches: Zi (zǐ), Chou (chǒu), Yin (yín), Mao (mǎo), Chen (chén), Si (sì), Wu (wǔ), Wei (wèi), Shen (shēn), You (yǒu), Xu (xū), Hai (hài).

Connecting the Heavenly Stems and the Earthly Branches forms a year of the Heavenly Stems and Earthly Branches, for example: Jiazi.

20202020 is the Year of the Boxer.

Every year, the celestial and terrestrial branches move to the next. For example, 20212021 is the year of Xin Chou.

Every 6060 years, the Heavenly Stems will cycle 66 times, and the Earthly Branches will cycle 55 times, so the Heavenly Stems and Earthly Branches will reincarnate every 6060 years. For example, 1900-1900, 1960-1960, and 2020-2020 are all gengzi years.

Given a year in AD, please output the year of the zodiac.

 Analysis of the problem: check the remainder and match the subscript to the celestial stem

Store it in a list because the subscript of the array starts from 0, it may get stuck here.

Solution: Take Tiangan (subscript from 0 to 9) as an example, such as input n=2027, because the subscript corresponding to 2020 is 6 (gengzi) at the beginning, after 7 years, count it, you will find that 2027 corresponds to The subscript should be 3,

If you directly (7)%9 will find that equal to 2 does not meet our expectations.

I thought of a way to treat the subscripts 0-9 as 1-10, so I only need (#years of change)%10-1

Where the details are :

What if the number of years of change is negative? That is, what if the subscript is negative?

Emm, you can find a few smaller than 2020 to try, and put them up if you can. (Because mathematical laws are usually concise and not so complicated!!)

AC code: 

a=['jia',
   'yi',
   'bing',
   'ding',
   'wu',
   'ji',
   'geng',
   'xin',
   'ren',
   'gui']

b=['zi',
   'chou',
   'yin',
   'mao',
   'chen',
   'si',
   'wu',
   'wei',
   'shen',
   'you',
   'xu',
   'hai']
n=int(input())
print(a[(7+n-2020)%10-1]+b[(1+n-2020)%12-1])

2. Evaluation (fill in the blank)

 This question and [Blue Bridge Cup National Championship] prepare for 24 days of Python - Py Xiaozheng's Blog - CSDN Blog

In the article I wrote before: The factorial factor is almost the same

My thinking process for this question is that the first step must be violent enumeration, but since the upper limit of violent enumeration is related to the size of the array m, m[i] represents the number of times the prime number i appears, (if i is an even number, We have initialized it to 1. As for why the question in the blog above is detailed), when the upper limit is very large, m is often too large, the time is too long, and the method is not suitable.  But with the experience of the previous question, I already have the divisors of any number within 100, print them out, that is, execute the following statement, observe, and find that if two numbers are taken, they are mutually prime If, then,

for i in range(1,101):
    print(i,find(i))
#find(i)在下面有说

The number of divisors corresponding to their product is the product of the number of divisors of two numbers.

Therefore, with the divisors corresponding to 1-100, we can iterate, in detail:

Create an array p=[] , each element of p appears as a list, each list has two numbers, respectively store the specific number and the number of subdivisions corresponding to the specific number, that is, for example p=[[2, 2], [7,2]], we can know that there are two divisors of 2 and two divisors of 7. Since 2 and 7 are relatively prime, it can be iteratively generated [14,4]

Since it is impossible to achieve multiple iterations, after the first iteration, it is found that there are already qualified (just the answer 45360), then only need to verify at (1,45260), this is my idea: do the question Experience + Observation + Guess Verification

Because it is a fill-in-the-blank question hh, it turns out that there is only one number 45360 in (1, 45360), then it is him

 AC code

#把n分解为多个质数乘机(a1+1)(a2+1)..(an+1)==100退出

def find(n):
    s=1
    m=[1]*101#m[i]:质数i被分解的个数
    j=2
    while j<=n:
        if n%j==0:
            m[j]+=1
            n//=j
        else:
            j+=1
    for i in m:
        s*=i
    return s#返回约数个数
p=[]
for i in range(1,101):
    if find(i)%5==0 or find(i)%2==0:
        p.append([i,find(i)])
def gcd(a,b):
    while b:
        a,b=b,a%b
    return a

for i in range(1,len(p)):
    if gcd(p[i][0],p[i-1][0])==1:
        key=p[i][0]*p[i-1][0]
        val=p[i][1]*p[i-1][1]
        if [key,val] not in p:
            p.append([key,val])
           
St=float('inf')#St
for i in range(len(p)):
    for j in range(i+1,len(p)):
        if gcd(p[i][0],p[j][0])==1:
            if p[i][1]*p[j][1]==100:
                St=min(St,p[i][0]*p[j][0])
                print(p[i],p[j])

 3. Buns make up the number

 Problem Description:

Xiao Ming eats breakfast at a steamed bun shop almost every morning. He found that this steamed bun shop has N kinds of steamers, and the i-th steamer can hold Ai buns exactly. Each type of steamer has a very large number of cages, which can be considered as infinite cages.

  Whenever a customer wants to buy X steamed buns, the uncle who sells steamed buns will quickly select several cages of steamed buns, so that there are exactly X steamed buns in these cages. For example, there are 3 types of steamers, which can hold 3, 4 and 5 buns respectively. When a customer wants to buy 11 buns, the uncle will choose 2 cages of 3 plus 1 cage of 5 (may also choose 1 cage of 3 plus 2 cages of 4).

  Of course, sometimes Uncle Baozi can't make up the quantity that customers want to buy anyway. For example, there are 3 types of steamers, which can hold 4, 5 and 6 buns respectively. And when the customer wanted to buy 7 buns, the uncle couldn't come out.

  Xiao Ming wanted to know how many kinds of numbers there were that Uncle Baozi couldn't figure out.

Problem Analysis: Combine the conclusions of this question:

 Two numbers p, q are relatively prime, then the largest number that p and q cannot represent is pq-(p+q)

We boldly infer that if the number of n kinds of buns given is not coprime, then there are inf (infinite) many that cannot be represented

Otherwise, that is, gcd(a,b,c,d..)=1, there are limited numbers that cannot be represented

The maximum number of buns is 100, then the maximum coprime to 100 is 99.

In the number of n kinds of buns, the two largest ones can always be taken out , namely p, q, then the number after pq-(p+q)+1 can be represented, so we only need to count [1, pq How many unrepresentable numbers are there within -(p+q])

Let p>q, then pq-(p+q)<pq<=9900, so no matter how many kinds of coprime buns are given, we need to search in the range of [1,9900] at most (here needs to be well understood For a moment, imagine the interval)

The following discusses how to search: Since there is an infinite number of buns, I think of the complete knapsack problem

The difference between two-dimensional complete knapsack and two-dimensional 01 knapsack is  dynamic programming - complete knapsack problem - Programmer Sought

It can be understood like this: dp[i][j] in the 01 knapsack problem is set to the maximum value of the j items before the capacity i

Complete knapsack problem dp[i][j] represents the maximum value of j items with capacity i

So in the 01 backpack dp[i][j] in the recurrence relationship, it may be transferred to dp[i-weight[j]][j-1]+val[j], j minus 1, because the items are limited;

In the complete knapsack problem, it may be transferred to dp[i-weight[j]][j]+val[j], and j is unchanged, because the item is infinite, it is understood that the space for weight[j] is reserved, and the first j is used. The maximum value that can be collected from various items, then this understanding means that the jth item is used more than once. Then this problem can be solved easily~

AC code 

n=int(input())
a=[0]*n
for i in range(n):
    a[i]=int(input())

def gcd(a,b):
    while b:
        a,b=b,a%b
    return a

def l_gcd(nums):
    if len(nums)==1:
        return nums[0]
    elif len(nums)==2:
        return gcd(nums[0],nums[1])
    else:
        return gcd(l_gcd(nums[:len(nums)//2]),l_gcd(nums[len(nums)//2:]))

if l_gcd(a)!=1:#这n个数字的最大公约数不等于1
    print('INF')

else:#这n个数字的最大公约数等于1,有解
    #区间确定,取n个数字里面最大的两个p,q
    #那么在正整数集合,pq-(p+q)+1开始之后均可以表示,所以[1,9900]
    ans,res=1,0
    a.insert(0,0)
    top=10000
    
    dp=[[0]*(n+1)for i in range(0,top+1)]#目标为i,前j种包子(每种包子数量无限)能不能凑出来
    for i in a:
        dp[i]=[1]*(n+1)

    for i in range(1,top+1):
        for j in range(1,n+1):
            if a[j]>i:
                dp[i][j]=dp[i][j-1]
            else:
                dp[i][j]=max(dp[i][j-1],dp[i-a[j]][j])
    v=0
    for k in range(1,len(dp)):
        if 1 not in  dp[k]:
            v+=1
    print(v)
            

 4.K times interval (provincial competition questions)

Problem description: Given a sequence of length N, A1, A2, ... AN, if the sum of a continuous subsequence Ai, Ai+1, ... Aj (i <= j) is a multiple of K , we call this interval [i, j] a K times interval.

Can you find the total number of K-fold intervals in the sequence?

Problem analysis: known (a+b)%p=(a%p+b%p)%p

Derivation process, set a=xp+y, b=mp+n, then (a+b)%p=((x+m)p+y+n)%p=(y+n)%p

That is, (a%p+b%p)%p is proved

Then, for this question, you also need to use the prefix sum, let Si>Sj, then the sum represented by Si-Sj is the interval [j+1,i]

As proposed (Si-Sj)%k==0 then (Si%k-Sj%k)%k==0

Then Si%k=Sj%k, so use this condition:

According to the sample input, we store the array a=[1,2,3,4,5]

Prefix and array [1,3,6,10,15], prefix and remainder array z=[1,1,0,0,1]

We found that z[0], z[1], z[4]=1, then the three intervals [1], [1,4], [2,4] are consistent, and those who understand permutation and combination should understand that it is equal to C(n, 2), there are three kinds of

Then we find that z[2], z[3]=0, then the interval [3] is consistent, and here we add the first 3 kinds, a total of 4 kinds

Where have the other two gone? List all the intervals, and you will find that because our subscript starts from 0, the left endpoint of the interval must be greater than or equal to 1, so the subscript 0 cannot be taken, so we insert a 0 at the top of the array a, The prefix sum array and the prefix sum remainder array change accordingly. You will find that there are exactly 3 0s now, C(3,2)=3

A total of 6 types are in line with expectations, so make good use of the sample, compare the actual and real requirements of your own program , find out what is missing, think about it, and boldly make up the conditions, the problem can often be solved.

AC code

n,k=map(int,input().split())

a=[0]*n

for i in range(n):
    a[i]=int(input())
a.insert(0,0)
s=[0]*(n+1)#前缀和

s[0]=a[0]
for i in range(1,n+1):
    s[i]=s[i-1]+a[i]

#对s[i] mod k,代表前i项和对k取余后的余数

z=[0]*(n+1)
for i in range(n+1):
    z[i]=s[i]%k

ans=0

p=dict()
for i in range(n+1):
    if z[i] not in p.keys():
        p[z[i]]=1
    else:
        p[z[i]]+=1

for j in p.values():
    ans+=int(j*(j-1)/2)
print(ans)

5. Frog Jumping Cup 

Naihe Xiaozheng didn't write it out. It's a BFS template question. Find the minimum number of times. 66 minutes timed out 

But let’s sum it up: BFS needs a queue queue, pre records the precursor nodes, searched records the visited nodes, and the judge function judges whether it is legal or not . That’s all . (The code can be seen, no AC)

st=input()
end=input()

queue=[st]

step=0

searched=[]
pre={}
dx=[-3,-2,-1,1,2,3]
def judge(new):
    global searched,pre
    if new not in searched and new not in pre.keys():
        return True
    return False
def change(tmp,now_index,new_index):
    y=list(tmp)
    y[now_index],y[new_index]=y[new_index],y[now_index]
    return ''.join(y)
   
    
while queue:
    tmp=queue.pop(0)
    if tmp==end:
        step=1
        while pre[tmp]!=st:
            step+=1
            tmp=pre[tmp]
        print(step)
        break
    else:
        #BFS搜6个方向,索引*位置
        now_index=tmp.index('*')
        for i in range(6):
            new_index=now_index+dx[i]
            if 0<=new_index<=len(tmp)-1:
                new=change(tmp,now_index,new_index)
                if judge(new):
                    searched.append(new)
                    queue.append(new)
                    pre[new]=tmp

Learning is like sailing against the current. If you don't advance, you will retreat. I hope everyone can get ideal results in this provincial competition.

If you have any questions, please leave a message and ask questions!

Guess you like

Origin blog.csdn.net/m0_62277756/article/details/123575938