第十三届蓝桥杯国赛Python 大学C组

非题解 仅仅是自己的个人思路!!!

希望能为你提供一些思路,目前不确定正确与否,大家有更好好的思路也可以一起讨论~~~

目录

A:斐波那契与7

B:小蓝做实验

C:取模

D:内存空间

E:斐波那契数组

F: 最大公约数

G: 交通信号

H: 点亮

 I: owo

J: 宝石收集


A:斐波那契与7

解题思路:

  • 当前项个位 只与前两项的个位有关      (十位百位... 相加 影响不到个位)
  • 那么当相邻两项的个位在之前出现过时  即又会反复1 1 2 3 5... 即会周期循环下去

思考:要想后面项的个位又重复出现3 5 那么前面两项 必然是1 2 而1 2 两项前面又必然是 0 1 

所以可以发现 0 1 1 2 3 5 是绑定死的 所以可以判断下一次出现1 1 即为下一次周期的开始

#ans:26960268160

#暴力:返回1-n项之间的数列7的个数
def fun1(n): 
    res = 0
    a,b = 1,1
    for i in range(3,n + 1):
        if (a + b) % 10 == 7:res += 1
        a,b = b,(a + b) % 10
    return res

#利用周期性:返回1-n项之间的数列7的个数
def fun2(n):
    res = 0
    res = (n // 60) * 8 + fun1(n % 60)
    return res

if __name__ == "__main__":
    n = int(input().strip())
    print("fun2",fun2(n))
##    以下是我找周期和计算该周期里7的个数的过程
##    Set,a,b,t = ['1 1'],1,1,0
##    while True:
##        s = str(b % 10) + ' ' + str((a + b) % 10)
##        if s in Set:break
##        else:Set.append(s)
##        a,b = b,a + b
##        if b % 10 == 7:t += 1
##    print(t,len(Set))
##    print(fun1(n % 61))

B:小蓝做实验

解题思路:利用输入流 暴力判断即可 大概3分钟之内

#ans:342693
import fileinput
def check(x):
    i = 2
    while i * i <= x:
        if x % i == 0:return False
        i += 1
    return True


if __name__ == "__main__":
    f = fileinput.input(files="C:/Users/Aoung/Desktop/LQ2022SF_PC/primes.txt")
    cnt = 0
    while True:
        try:
            if check(int(f.readline().strip())):cnt += 1       
        except:
            break
    print(cnt)

C:取模

解题思路:暴力~~~   蒟蒻代码就不贴了

D:内存空间

解题思路:模拟   需要注意的点是 给的样例中的双引号居然是中文的? 十分不合理,如果后续测评又不是中文状态那就坑人了,如果是中文那代码中的双引号怎么能是中文。。。

def find(s):
    if s.find("int") != -1:return 4
    elif s.find("long") != -1:return 8
    else:return 1

#将x转换为合适的形式
def tostring(x):
    a = [0,0,0,x % 1024]
    for i in range(2,-1,-1):
        x //= 1024
        a[i] = x % 1024
    f = ["GB","MB","KB","B"]
    for i in range(4):
        if a[i] != 0:print(str(a[i]) + f[i],end = '')
    



if __name__ == "__main__":
    T = int(input().strip())
    res = 0#最终的B的大小
    while T:
        s = input().strip().split(maxsplit=1)
        m = find(s[0])
        if s[0][-1] == ']':
            ss = s[1].split("[")
            i = 1
            while i < len(ss):
                res += int(ss[i][:ss[i].find("]")]) * m 
                i += 1
        else:
            if m == 1:
                ss = s[1].split("”")
                i = 1
                while i < len(ss):
                    res += len(ss[i])
                    i += 2
            else:
                res += s[1].count("=") * m
        T -= 1
    tostring(res)

E:斐波那契数组

解题思路:看了一下数据范围

  •  以1 1 开头的斐波那契数组第30项之后就一定会大于1e6 但是数据范围给的项数有1e5 所以我们30项之后的必定是需要修改的
  • 倍数关系 2 2 开头的斐波那契数组中对应的每一项都是原斐波那契数组的2倍 以3 3开头为3倍以此类推
  • 所以我们只需要判断前30项和哪个开头的斐波那契数组最契合(即最少需要修改多少即可) 我们可以枚举前2-29项 判断该项是否是原斐波那契数组(1 1 2 3)中对应项的倍数
  • 若是 则该项对应的倍数的斐波那契数组 可能成为答案 就检查一下即可 
  • 若不是 则说明该项一定需要修改 跳过
def check(k):
    cnt = 2
    if w[0] == k:cnt -= 1
    if w[1] == k:cnt -= 1
    for i in range(2,len(a)):
        if w[i] != a[i] * k:cnt += 1
    return cnt



if __name__ == "__main__":
    n = int(input())
    a,w = [1,1],list(map(int,input().strip().split()))
    for i in range(2,n):
        a.append(a[i - 1] + a[i - 2])
        if a[-1] > 1e6:
            a.pop()
            break
    res = n - 2 + (1 if w[0] != w[1] else 0)
    #寻找基准值 30项后所有的数都>1e6 所以必须改
    for i in range(2,min(30,len(a))):
        if w[i] % a[i] == 0:
            res = min(res,check(w[i] // a[i]) + max(0,n - 30))
    print(res)

F: 最大公约数

解题思路:

  • 我们需要将数列的每一项变成1 而变换的规则是相邻两项的最大公约数 如果数列存在1 我们就好办了 因为1和任何数的最大公约数一定是1  如 5 3 2 7 1 6 1 我们只需要找到不是1的数的个数就是需要变换的次数
  • 情况1 原数组已经存在1 那么答案就是不是1的数个数
  • 情况2 原数组不存在1 那么我们就BFS枚举每一项可能变换的情况 看最快几步会变成1 存在1后就可以结束了 就变成了情况1

蒟蒻:判断答案为-1 是直接如果变换1000次还不存在1的情况 则无解

大佬说:判断该数组所有数的最大公约数是否为1 若是 则有解 否则无解

from math import gcd
#最快几次让其中的任意一个元素变为1

if __name__ == "__main__":
    n = int(input().strip())
    w = list(map(int,input().strip().split()))
    if 1 in w:
        print(n - w.count(1))
    else:
        a,cnt = [[_] for _ in w],0
        flag = False
        while True:
            p = [set() for _ in range(n)]
            for i in range(n - 1):
                for j in a[i]:
                    for k in a[i + 1]:
                        t = gcd(j,k)
                        if t == 1:flag = True
                        p[i].add(t)
                        p[i + 1].add(t)
            cnt += 1
            if flag or cnt > 1000:break
            a = p
        if cnt > 1000:print(-1)
        else:print(cnt + n - 1)


G: 交通信号

解题思路:BFS 感觉难点主要是判断走到该路口时判断下一次走到对应的位置要等多久

import heapq
def check(l,g,r,d,f):
    s = (g + r + 2 * d)
    l %= s
    if f == 0:
        #求当前状态离下一次绿灯要等多久
        if l < g:return 0
        else:return s - l
    else:
        if (g + d) <= l < (g + d + r):return 0
        else:return (g + d - l + s) % s


def run():
    que,vis = [(0,s)],[False] * (n + 1)
    flag = False
    while que:
        t = heapq.heappop(que)
        if vis[t[1]]:continue
        vis[t[1]] = True
        if t[1] == end:
            flag = True
            print(t[0])
            break
        for v,g,r,d,f in h[t[1]]:
            if vis[v]:continue
            heapq.heappush(que,(t[0] + check(t[0],g,r,d,f) + d,v))
    if not flag:print(-1)
            

if __name__ == "__main__":
    n,m,s,end = map(int,input().strip().split())
    h = [[] for _ in range(n + 1)]
    for i in range(m):
        u,v,g,r,d = map(int,input().strip().split())
        h[u].append((v,g,r,d,0))
        h[v].append((u,g,r,d,1))
    run()

H: 点亮

 I: owo

解题思路:暴力

#计算有多少个owo
def count(ss):
    l,res = ss.find("owo"),0
    while l != -1:
        res += 1
        l = ss.find("owo",l + 1)
    return res


def dfs(cnt,oc,p,fron):
    if cnt == fron:
        res[0] = max(res[0],oc)
        return
    
    for i in range(fron):
        if st[i]:continue
        st[i] = True
        pp = p + s[i]
        if len(pp) <= 1:t = pp
        else:t = pp[-2] + pp[-1]
        dfs(cnt + 1,oc + count(pp),t,fron)
        st[i] = False


if __name__ == "__main__":
    n = int(input().strip())
    s = [input().strip() for _ in range(n)]
    st = [False] * n
    for i in range(1,n + 1):
        res = [0]
        dfs(0,0,"",i)
        print(res[0])

J: 宝石收集

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值