• 第十三届蓝桥杯国赛真题 PythonB组 复盘以及获奖感言(国一!!!)


    第十三届蓝桥杯国赛真题 PythonB组 复盘以及获奖感言(国一)


    img

    🏆 获奖感言

    国一开心! 国一开心! **国一开心!**重要的词说三遍,这个国赛确实让我有点惊喜,我居然拿到国赛一等奖!!!

    从今年年初开始,慢慢的捡起曾经的数据结构的知识以及很多算法的知识,努力学习,在5月的时候,成功拿到了省一等奖,当时其实我都感觉我要凉了,感觉彻底没什么希望了,只希望自己能够拿一个省二吧,但是我的目标一开始就是国赛,不过不是国一,而是国二。

    我和我的朋友努力学习,互相交流,我觉得在打比赛的时候,在学习的时候,有一个志同道合的朋友是很好的,也有很多人会加群,然后不断交流学习,这样的学习方式我感觉是不错的,大家可以互相思考,互相借鉴对方的思路,互相分享一些不错的知识点,这样我们就可以达到教学相长也的情况,而且大家也是一起努力的,一起比赛,最后我和我朋友分别我是国一,他国二,可谓是皆大欢喜。

    其实蓝桥杯相对很多赛事来说,获奖的比例还是高的,比如在省一,可以有70%的人获奖,当然省一只有10%,在国赛,取前5%的为国一,15%为国二,20%为国三,不过实际上是加和的,也就是5+15+20=45,国赛有45%获奖,其他人只要不是0分都可以评个简单的优秀奖,不虚此行哈哈哈

    随着时代的发展,蓝桥杯也不再是暴力杯了,特别今年开始,填空题只有2道,投机取巧的机会比较少了,我省一填空题只作出一道,但是国赛填空题好像一道都没有对,感觉还是慢慢变难了,也听说A组的题目也是很难的,所以慢慢蓝桥杯也调整了题目的分布和难度,而不仅仅是暴力搜索的解题,但是不可置疑的是,暴力解题还是可以得到一部分的分的。

    总的来说,这次蓝桥杯之行还是圆满的,拿到了国赛的一等,为我的前途铺了层砖,也希望之后的大家也努努力,你们也一定可以的

    试题A: 斐波那契与7

    在这里插入图片描述

    思路

    这道题来说,其实看起来是很简单的,所以我想的也很简单,就是穷举,然后%10,最后一项为7的就+1,但是这个数据太大了,我运行了好久好久都没有出来,最后我利用C++去写这道题,然后也运行了2h以上,得到一个答案。

    但是后面我发现,如果每次加的时候都%10,得到的结果不一定是正确的,所以最后这道题我应该是错误的,填空题,太难了呀,这穷举不出来啊。本来还想着用快速幂,不过最后还是放弃了。

    代码

    a,b=1,1
    n = 202202011200
    ans = 0
    for i in range(n-2):
        a,b = b%10,(a+b)%10
    ##    print(b)
        if b%10 == 7:
            ans += 1
    print(ans)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    试题B: 小蓝做实验

    在这里插入图片描述

    思路

    这道题来说,很简单,利用线性筛或者是埃氏筛,但是问题就是,我用了线性筛,虽然对于线性筛来说,我们的计算素数是很快的,但是整个数据其实还是很大很大,我朋友跟我说,其实我们先应该筛选,这个范围是10的3次方到10的12次方,总的来说,就是数据太大,用的方法稍微的有点不对劲,结果还是没跑出来,我python真的很久,绝望!!!

    代码

    n = 100000000
    isprime = [False]*(n+1)
    primes = [0]*(n+1)
    cnt = 0
    
    for i in range(2,n):
        if not isprime[i]:
            primes[cnt] = i
            cnt += 1
        for j in range(cnt):
            if i*primes[j] > n: break
            isprime[i*primes[j]] = True
            if i%primes[j] == 0: break
    primes = primes[:cnt]
    
    res = 0
    f = open('primes.txt')
    data = f.readlines()
    print(len(data))
    for i in range(len(data)):
        x = data[i].replace('/n','')
        x = int(x)
        if x in primes:
            res += 1
        if i%1000 == 0:
            print(i,res)
    print(res)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    试题C: 取模

    在这里插入图片描述

    样例输入

    3
    1 2
    5 2
    999 99
    
    • 1
    • 2
    • 3
    • 4

    样例输出

    No
    No
    Yes
    
    • 1
    • 2
    • 3

    提示

    对于 20% 的评测用例,T ≤ 100 ,n, m ≤ 1000;

    对于 50% 的评测用例,T ≤ 10000 ,n, m ≤ 105;

    对于所有评测用例,1 ≤ T ≤ 105 ,1 ≤ n ≤ 109 ,2 ≤ m ≤ 109。

    思路

    这道题完全没有什么思路,直接暴力即可,时间有限,还不如做下一道题

    (后面来看,暴力还是能拿一半的分的,不亏不亏 https://www.dotcpp.com/oj/problem2735.html)

    代码

    t = int(input())
    for i in range(t):
        n,m = map(int,input().split())
        flag = False
        for x in range(1,m):
            for y in range(x+1,m+1):
                if n%x == n%y:
                    flag = True
                    break
            if flag:
                break
        if flag:
            print('Yes')
        else:
            print('No')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    试题D:内存空间

    在这里插入图片描述

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SUiQHcY0-1656651026729)(C:\Users\86137\AppData\Roaming\Typora\typora-user-images\image-20220701111108884.png)]

    在这里插入图片描述

    样例输入1

    1
    long[] nums=new long[131072];
    
    • 1
    • 2

    样例输出1

    1MB
    
    • 1

    样例输入2

    4
    int a=0,b=0;
    long x=0,y=0;
    String s1=”hello”,s2=”world”;
    long[] arr1=new long[100000],arr2=new long[100000];
    
    • 1
    • 2
    • 3
    • 4
    • 5

    样例输出2

    1MB538KB546B
    
    • 1

    在这里插入图片描述

    思路

    这道题,我觉得单纯就是对字符串进行一个操作,我们可以看到有两种类型,我们分别对两种类型进行操作

    不过每一种类型来说,首先,我们都是要将我们的数据分开,相同的特点就是,他们都是以逗号进行分割的,所以我们可以用split(‘,’)很简单的分开。然后根据不同的int,char以及string来判断字符的大小和长度即可。

    对于第二种类型来说,稍微复杂一点,但是思路还是很清晰的,就是我们可以找到左右两个中括号,然后对立面进行计数,而且他仅仅有两种类型,分别是int和long,这样的判断就更简单了。

    最后我们可以得到我们的空间大小,但是我们需要进行化简,根据1GB=1024MB,1MB=1024KB,1KB=1024B,得到最后的结果,可以说,这道题是我比较有信心的题。

    代码

    t = int(input())
    
    res = 0
    for i in range(t):
        s = input()
        if '[]' in s:
            a = s.split(',')
            # print(a)
            if s[0] == 'i':
                for x in a:
                    left = x.rfind('[')
                    right = x.rfind(']')
                    ans = int(x[left+1:right])
                    print(ans)
                    res += ans*4
                pass
            elif s[0] == 'l':
                for x in a:
                    left = x.rfind('[')
                    right = x.rfind(']')
                    ans = int(x[left+1:right])
                    res += ans*8
        else:
            a = s.split(' ')
            tp,var = a[0],a[1]
            if tp == 'int':
                x = len(a[1].split(','))
                res += x*4
            elif tp == 'long':
                x = len(a[1].split(','))
                res += x*8
            elif tp == 'String':
                x = a[1].split(',')
                for y in x:
                    res += len(y.split('=')[1]) - 2
                res -= 1     
    GB = res//(1024*1024*1024)
    MB = res//(1024*1024) - GB*1024
    KB = res//(1024) - GB*1024*1024 - 1024*MB
    B = res%1024
    if GB != 0:
        print('%dGB'%GB,end='')
    if MB != 0:
        print('%dMB'%MB,end='')
    if KB != 0:
        print('%dKB'%KB,end='')
    if B != 0:
        print('%dB'%B,end='')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    试题E: 近似GCD

    在这里插入图片描述

    在这里插入图片描述

    样例输入

    5 3
    1 3 6 4 10
    
    • 1
    • 2

    样例输出

    5
    
    • 1

    提示

    满足条件的子数组有 5 个:

    [1, 3]:将 1 修改为 3 后,这个子数组的最大公约数为 3 ,满足条件。

    [1, 3, 6]:将 1 修改为 3 后,这个子数组的最大公约数为 3 ,满足条件。

    [3, 6]:这个子数组的最大公约数就是 3 ,满足条件。

    [3, 6, 4]:将 4 修改为 3 后,这个子数组的最大公约数为 3 ,满足条件。

    [6, 4]:将 4 修改为 3 后,这个子数组的最大公约数为 3,满足条件。

    对于 20% 的评测用例,2 ≤ n ≤ 102;

    对于 40% 的评测用例,2 ≤ n ≤ 103;

    对于所有评测用例,2 ≤ n ≤ 105 ,1 ≤ g, ai ≤ 109。

    思路

    这道题来说的话,其实有点复杂,我也不知道我的算法对不对。我一开始想着是否可以用DP解决,但是没有一个固定的思路,最后我直接穷举两端,然后对数据进行求gcd,如果发现有数据算出来不是期望的g,那我就进行修改,如果修改两次,就直接退出,说明这个子数组是不符合的。

    这道题最后,应该也是暴力得了些许分,肯定不是满分的,也可以去测试一下https://www.dotcpp.com/oj/problem2727.html

    代码

    n,g = map(int,input().split())
    a = list(map(int,input().split()))
    
    from math import gcd
    res = 0
    for i in range(n-1):
        for j in range(i+1,n):
            x = a[i:j+1]
            ans = g
            flag = True
            flag2 = True
            # 判断所有的和
            for y in x:
                if y%g != 0:
                    if flag:
                        flag = False
                        y = g
                    else:
                        flag2 = False # 修改第二次
                        break
                ans = gcd(ans,y)
                if ans != g:
                    break
            # print(x,ans)
            if ans == g and flag2:
                res += 1
    
    print(res)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    试题F: 交通信号

    在这里插入图片描述

    样例输入

    4 4 1 4
    1 2 1 2 6
    4 2 1 1 5
    1 3 1 1 1
    3 4 1 99 1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    样例输出

    11
    
    • 1

    思路

    这道题其实可以用迪杰斯特拉算法,构建双向边进行求解,但是考试的时候并没有想出来,所以最简单的可以拿分的就是,print(-1)

    代码

    print(-1)
    
    • 1

    试题G: 点亮

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    思路

    没思路,写不出来,不过可以穷举2x2的方格捞分

    代码

    暂无

    试题H: 打折

    在这里插入图片描述

    样例输入

    2 2
    1 2 89 1
    1 97
    3 4 77 1
    2 15
    
    • 1
    • 2
    • 3
    • 4
    • 5

    样例输出

    101
    
    • 1

    提示

    对于 40% 的评测用例,n, m ≤ 500 ,si ≤ ti ≤ 100 ,∑ ci ≤ 200000 ;

    对于 70% 的评测用例,n, m ≤ 5000 ,∑ ci ≤ 200000 ;

    对于所有评测用例,1 ≤ n, m ≤ 100000,1≤ ci≤ n , ∑ ci ≤ 400000 ,1 ≤ si ≤ ti ≤ 109 ,1 < pi < 100 ,1 ≤ aj ≤ n ,1 ≤ bj ≤ 109 。

    思路

    这道题,就是一个暴力,找一下每个时间段中费用最低的,然后全部买一遍,最后遍历取最大的结果

    这应该不是正解,但是考试的时间那时候还是比较紧张,我就先简单暴力写一下。

    这道题最后,应该也是暴力得了些许分,肯定不是满分的,也可以去测试一下https://www.dotcpp.com/oj/problem2730.html

    代码

    n,m = map(int,input().split())
    from collections import defaultdict
    prices = defaultdict(list)
    days = 0
    for i in range(n):
        s,t,p,c = map(int,input().split())
        days = max(days,t)
        for j in range(c):
            a,b = map(int,input().split())
            price = b*p//100
            prices[a].append([price,s,t])
            prices[a].append([b])
    
    ##print(prices)
    min_price = float('inf')
    for day in range(days):
        res = 0
        for k,v in prices.items():
            v.sort()
            # print(v)
            for p in v:
                if len(p) == 3:
                    if p[1] <= day <= p[2]:
                        ans = p[0]
                        break
                else:
                    ans = p[0]
                    break
            res = res + ans
    ##        print(res)
        min_price = min(res,min_price)
    print(min_price)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    试题I: owo

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    思路

    这道题的思路也是穷举,但是这里面用了一下全排列函数,然后将数据排序,判断最长的结果。

    时间有限,也没想好有什么好的方法,不过这个肯定能拿10+分的,40+分不知道有没有机会

    代码

    n = int(input())
    
    def get_owo(sr):
        l = len(sr)
        x = sr.find('owo')
        ans = 0 
        if x == -1:
            return 0
        else:
            ans = 1
        for i in range(x+2,l,2):
            # print(sr[i:i+3])
            if sr[i:i+3] == 'owo':
                ans += 1
    
        return ans
    
    a = []
    from itertools import permutations
    for i in range(n):
        s = input()
        a.append(s)
        res = 0
        b = list(set(permutations(a)))
        for x in b:
            sr = ''.join(x)
    ##        print(sr)
            ans = get_owo(sr)
            res = max(res,ans)
        print(res)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    试题J: 替换字符

    在这里插入图片描述

    样例输入

    abcaaea
    4
    1 7 c e
    3 3 e b
    3 6 b e
    1 4 a c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    样例输出

    cbecaea
    
    • 1

    提示

    对于 40% 的评测用例,|s|, m ≤ 5000;

    对于所有评测用例,1 ≤ |s|, m ≤ 105 ,1 ≤ li ≤ ri ≤ |s| ,xi 不等于 yi ,其中 |s| 表示字符串 s 的长度。

    思路

    这道题,直接就是区间修改,感觉是线段树,但是好像模板套的又不是很可以,之后就没有一个很好的想法了

    最后利用python将部分字母进行替换,我们就可以直接用replace,用replace就可以简单的过了一部分的数据,应该是40%的数据

    这道题最后,应该也是暴力得了些许分,也可以去测试一下https://www.dotcpp.com/oj/problem2739.html

    代码

    s = input()
    
    n = int(input())
    
    for _ in range(n):
        l,r,x,y = input().split()
        l,r = int(l),int(r)
        tmp = s[l-1:r].replace(x,y)
    ##    print(tmp)
        s = s[:l-1] + tmp + s[r:]
        # print(s)
    print(s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    【第五周】函数和代码复用
    一款.Net7前后端分离、跨平台的通用权限管理框架
    Mysql事务隔离级别与MVCC(多版本并发控制)
    无刷电机FOC硬件方案
    【自然语言处理(NLP)】基于ERNIE-GEN的中文自动文摘
    Python中的文件I/O操作:常见问题与解决方案
    基于Python实现的图的同构算法
    基于YOLO实现的口罩佩戴检测 - python opemcv 深度学习 计算机竞赛
    疫情可视化part3
    c#学习_第四弹
  • 原文地址:https://blog.csdn.net/weixin_45508265/article/details/125554679