当前位置:   article > 正文

【python语言】第十四届蓝桥杯国赛 c/c++b组_蓝桥杯国赛c++b组

蓝桥杯国赛c++b组

一、子2023.

1. 考点:动态规划
2. 难度:⭐⭐⭐
3. 要点分析:

本题有两种做法,

(1)暴力求解。虽然时间复杂度挺高(跑了挺久),但在一定时间内是能够跑出正确答案的。

  1. seq = ''
  2. for i in range(1,2023+1):
  3. seq += str(i)
  4. s = ''
  5. for t in seq:
  6. if t in ['2','0','2','3']:
  7. s += t
  8. ans = 0
  9. for i in range(len(s)):
  10. if s[i]=='2':
  11. for j in range(i+1,len(s)):
  12. if s[j]=='0':
  13. for p in range(j+1,len(s)):
  14. if s[p]=='2':
  15. for q in range(p+1,len(s)):
  16. if s[q]=='3':
  17. ans += 1
  18. print(ans)

(2)动态规划。对于我本人来说比较难想一点,但确实开拓了一个新思路。

每多增加一个“2”,dp[0]+1,且对应的“202”的数目(dp[2])也会增加1*dp[1]个;

每多增加一个“0”,“20”的数目(dp[1])会增加1*dp[0]个;

每多增加一个“3”,“2023”的数目(dp[3])会增加多1*dp[2]个。

  1. seq = ''
  2. for i in range(1,2023+1):
  3. seq += str(i)
  4. s = ''
  5. for t in seq:
  6. if t in ['2','0','2','3']:
  7. s += t
  8. """分别代表 2 20 202 2023"""
  9. dp = [0]*4
  10. for t in s:
  11. if t=='2':
  12. dp[0] += 1
  13. dp[2] += dp[1]
  14. if t=='0':
  15. dp[1] += dp[0]
  16. if t=='3':
  17. dp[3] += dp[2]
  18. print(dp[-1])

【考试时实在不行第一种,但练习时要学习第二种哈哈哈~】

二、双子数。

1. 考点:质因子分解
2. 难度:⭐⭐
3. 要点分析:

①在双层循环中,若不增加一些“筛选条件”,或是从start~end开始循环,时间复杂度都会比较大。

  1. import math
  2. def check(x):
  3. for i in range(2,int(math.sqrt(x))+1):
  4. if x%i==0:
  5. return 0
  6. return 1
  7. """将x开方 变为p*q的数 找到其中的p和q"""
  8. start = int(math.sqrt(2333))
  9. end = int(math.sqrt(23333333333333))
  10. prime = [2,]
  11. for i in range(3,end+1):
  12. if check(i):
  13. prime.append(i)
  14. vis = [0]*(end+1)
  15. for p in range(len(prime)):
  16. for q in range(p+1,len(prime)):
  17. x = prime[p]*prime[q]
  18. if x>end:
  19. break
  20. if x<start:
  21. continue
  22. vis[x] = 1
  23. print(sum(vis[start:]))

②尽管本次不需要对“素数的判断”进行优化,但还是记住“欧拉筛”比较好,说不定下次能够用上。其基本思想是,素数的倍数不是素数。

  1. def ouler(r):
  2. primes = []
  3. check = [True for i in range(r+1)]
  4. for i in range(2,r+1):
  5. if check[i]:
  6. primes.append(i)
  7. for j in primes:
  8. if i * j > r:
  9. break
  10. check[i*j] = False
  11. if i % j == 0:
  12. break
  13. return primes

三、班级活动。

1. 考点:思维
2. 难度:⭐⭐⭐
3. 要点分析(详细解析可参考):考虑清楚“可配对”的情况:①id数等于1的学生自由配对;②id数超过2的学生全部改变;③id数等于1的学生和id数超过2的学生配对,仅需改变id数超过2的学生的id。由此,结合“最少变动”,得出改变方案。

【洛谷 P9421】[蓝桥杯 2023 国 B] 班级活动 题解(计数排序+贪心算法+数学)-CSDN博客

  1. n = int(input())
  2. numbers = list(map(int, input().split()))
  3. ds = dict()
  4. """
  5. 有可能会出现同一数字出现多次的情况
  6. 每个数字只能出现两次 多于两次则需要更改
  7. """
  8. # 统计次数
  9. for t in numbers:
  10. if t not in ds.keys():
  11. ds[t] = 1
  12. else:
  13. ds[t] += 1
  14. x = 0 #待分配id的学生
  15. y = 0 #id重复的学生
  16. for t in list(ds.keys()):
  17. if ds[t] == 1:
  18. x += 1
  19. elif ds[t] > 2:
  20. y += ds[t]-2
  21. # x<=y 只需要改变id重复的学生即可
  22. if x<=y:
  23. print(y)
  24. # x>y 1.改变id重复的学生以适配;2.剩余待分配学生两两配对
  25. else:
  26. print((x-y)//2+y)

四、合并数列。

1. 考点:模拟、双指针
2. 难度:⭐⭐⭐
3. 要点分析:

①利用“双指针”时,不要改变指针指向的数组的内容;而是选择另一个衡量标准——“当前的数组和是否相等”。

②当使用“while循环”时,需格外注意其循环条件:有可能p==n-1,但此时q!=(m-1)且sumA!=sumB。但两个数组的数组和必然是相等的,因此只需要再合并数组余下的数即可。

  1. n, m = map(int, input().split())
  2. a = list(map(int, input().split()))
  3. b = list(map(int, input().split()))
  4. p=0;q=0
  5. sumA=0;sumB=0
  6. ans = 0
  7. while p<n and q<m:
  8. if sumA==sumB:
  9. sumA += a[p]
  10. sumB += b[q]
  11. p+=1;q+=1
  12. elif sumA<sumB:
  13. sumA += a[p]
  14. p += 1
  15. ans += 1
  16. elif sumA>sumB:
  17. sumB += b[q]
  18. q += 1
  19. ans += 1
  20. print(ans+n+m-p-q)

五、数三角。

1. 考点:枚举
2. 难度:⭐⭐⭐
3. 要点分析:该题解在pyp3能过,python只能达到65%。

①对于平面上的每一个点P,计算其与其它所有点的距离。

②以P点位顶点,计算其与其它两点能否构成三角形。

注:本题的思路不难,难在“优化”上;如何减少代码的时间复杂度。

  1. import math
  2. n = int(input())
  3. dots = []
  4. for i in range(n):
  5. x, y = map(int, input().split())
  6. dots.append([x,y])
  7. ans = 0
  8. # 以p点为圆心,记录不同点与点p的距离
  9. for p in range(n):
  10. dockers = {}
  11. for q in range(n):
  12. if p==q:
  13. continue
  14. x1,y1 = dots[p]
  15. x2,y2 = dots[q]
  16. dis = math.sqrt((x1-x2)**2+(y1-y2)**2)
  17. if dis not in dockers:
  18. dockers[dis] = [q]
  19. else:
  20. dockers[dis].append(q)
  21. for dis in dockers:
  22. if len(dockers[dis])>=2:
  23. # 判断是否能组成三角形
  24. for i in range(len(dockers[dis])):
  25. for j in range(i+1,len(dockers[dis])):
  26. x1,y1 = dots[dockers[dis][i]]
  27. x2,y2 = dots[dockers[dis][j]]
  28. tmp = math.sqrt((x1-x2)**2+(y1-y2)**2)
  29. if tmp < 2*dis:
  30. ans += 1
  31. print(ans)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/917618
推荐阅读
相关标签
  

闽ICP备14008679号