赞
踩
本题有两种做法,
(1)暴力求解。虽然时间复杂度挺高(跑了挺久),但在一定时间内是能够跑出正确答案的。
- seq = ''
- for i in range(1,2023+1):
- seq += str(i)
-
- s = ''
- for t in seq:
- if t in ['2','0','2','3']:
- s += t
-
- ans = 0
- for i in range(len(s)):
- if s[i]=='2':
- for j in range(i+1,len(s)):
- if s[j]=='0':
- for p in range(j+1,len(s)):
- if s[p]=='2':
- for q in range(p+1,len(s)):
- if s[q]=='3':
- ans += 1
- 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]个。
- seq = ''
- for i in range(1,2023+1):
- seq += str(i)
-
- s = ''
- for t in seq:
- if t in ['2','0','2','3']:
- s += t
-
- """分别代表 2 20 202 2023"""
- dp = [0]*4
- for t in s:
- if t=='2':
- dp[0] += 1
- dp[2] += dp[1]
- if t=='0':
- dp[1] += dp[0]
- if t=='3':
- dp[3] += dp[2]
- print(dp[-1])
【考试时实在不行第一种,但练习时要学习第二种哈哈哈~】
①在双层循环中,若不增加一些“筛选条件”,或是从start~end开始循环,时间复杂度都会比较大。
- import math
-
- def check(x):
- for i in range(2,int(math.sqrt(x))+1):
- if x%i==0:
- return 0
- return 1
-
- """将x开方 变为p*q的数 找到其中的p和q"""
- start = int(math.sqrt(2333))
- end = int(math.sqrt(23333333333333))
-
- prime = [2,]
- for i in range(3,end+1):
- if check(i):
- prime.append(i)
-
- vis = [0]*(end+1)
- for p in range(len(prime)):
- for q in range(p+1,len(prime)):
- x = prime[p]*prime[q]
- if x>end:
- break
- if x<start:
- continue
- vis[x] = 1
- print(sum(vis[start:]))
②尽管本次不需要对“素数的判断”进行优化,但还是记住“欧拉筛”比较好,说不定下次能够用上。其基本思想是,素数的倍数不是素数。
- def ouler(r):
- primes = []
- check = [True for i in range(r+1)]
- for i in range(2,r+1):
- if check[i]:
- primes.append(i)
- for j in primes:
- if i * j > r:
- break
- check[i*j] = False
- if i % j == 0:
- break
- return primes
【洛谷 P9421】[蓝桥杯 2023 国 B] 班级活动 题解(计数排序+贪心算法+数学)-CSDN博客
- n = int(input())
- numbers = list(map(int, input().split()))
- ds = dict()
-
- """
- 有可能会出现同一数字出现多次的情况
- 每个数字只能出现两次 多于两次则需要更改
- """
-
- # 统计次数
- for t in numbers:
- if t not in ds.keys():
- ds[t] = 1
- else:
- ds[t] += 1
-
- x = 0 #待分配id的学生
- y = 0 #id重复的学生
- for t in list(ds.keys()):
- if ds[t] == 1:
- x += 1
- elif ds[t] > 2:
- y += ds[t]-2
-
- # x<=y 只需要改变id重复的学生即可
- if x<=y:
- print(y)
- # x>y 1.改变id重复的学生以适配;2.剩余待分配学生两两配对
- else:
- print((x-y)//2+y)
①利用“双指针”时,不要改变指针指向的数组的内容;而是选择另一个衡量标准——“当前的数组和是否相等”。
②当使用“while循环”时,需格外注意其循环条件:有可能p==n-1,但此时q!=(m-1)且sumA!=sumB。但两个数组的数组和必然是相等的,因此只需要再合并数组余下的数即可。
- n, m = map(int, input().split())
- a = list(map(int, input().split()))
- b = list(map(int, input().split()))
-
- p=0;q=0
- sumA=0;sumB=0
- ans = 0
- while p<n and q<m:
- if sumA==sumB:
- sumA += a[p]
- sumB += b[q]
- p+=1;q+=1
- elif sumA<sumB:
- sumA += a[p]
- p += 1
- ans += 1
- elif sumA>sumB:
- sumB += b[q]
- q += 1
- ans += 1
- print(ans+n+m-p-q)
①对于平面上的每一个点P,计算其与其它所有点的距离。
②以P点位顶点,计算其与其它两点能否构成三角形。
注:本题的思路不难,难在“优化”上;如何减少代码的时间复杂度。
- import math
-
- n = int(input())
- dots = []
- for i in range(n):
- x, y = map(int, input().split())
- dots.append([x,y])
-
- ans = 0
- # 以p点为圆心,记录不同点与点p的距离
- for p in range(n):
- dockers = {}
- for q in range(n):
- if p==q:
- continue
- x1,y1 = dots[p]
- x2,y2 = dots[q]
- dis = math.sqrt((x1-x2)**2+(y1-y2)**2)
- if dis not in dockers:
- dockers[dis] = [q]
- else:
- dockers[dis].append(q)
-
- for dis in dockers:
- if len(dockers[dis])>=2:
- # 判断是否能组成三角形
- for i in range(len(dockers[dis])):
- for j in range(i+1,len(dockers[dis])):
- x1,y1 = dots[dockers[dis][i]]
- x2,y2 = dots[dockers[dis][j]]
- tmp = math.sqrt((x1-x2)**2+(y1-y2)**2)
- if tmp < 2*dis:
- ans += 1
- print(ans)
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。