记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
-
-
- [12/1 2141. 同时运行 N 台电脑的最长时间](#12/1 2141. 同时运行 N 台电脑的最长时间)
- [12/2 3623. 统计梯形的数目 I](#12/2 3623. 统计梯形的数目 I)
- [12/3 3625. 统计梯形的数目 II](#12/3 3625. 统计梯形的数目 II)
- [12/4 2211. 统计道路上的碰撞次数](#12/4 2211. 统计道路上的碰撞次数)
- [12/5 3432. 统计元素和差值为偶数的分区方案](#12/5 3432. 统计元素和差值为偶数的分区方案)
- [12/6 3578. 统计极差最大为 K 的分割方式数](#12/6 3578. 统计极差最大为 K 的分割方式数)
- 12/7
-
12/1 2141. 同时运行 N 台电脑的最长时间
二分 判断mid时长是否满足
容量大于mid的电池x 最多可以使用mid次
容量小于mid的电池x 最多使用batteries[x]次
统计总次数是否大于mid*n
python
def maxRunTime(n, batteries):
"""
:type n: int
:type batteries: List[int]
:rtype: int
"""
l,r,ans=0,sum(batteries)//n,0
while l<=r:
mid=(l+r)//2
total =0
for cap in batteries:
total += min(cap,mid)
if total >=n*mid:
ans=mid
l=mid+1
else:
r=mid-1
return ans
12/2 3623. 统计梯形的数目 I
统计每一行 有多少个点
构成一个梯形 任意两行 每行取两个点的可能性相乘
python
def countTrapezoids(points):
"""
:type points: List[List[int]]
:rtype: int
"""
from collections import defaultdict
MOD=10**9+7
m=defaultdict(int)
for p in points:
m[p[1]]+=1
totaledge,edge=0,0
ans=0
for pnum in m.values():
edge = pnum*(pnum-1)//2
ans = (ans+edge*totaledge)%MOD
totaledge = (totaledge+edge)%MOD
return ans
12/3 3625. 统计梯形的数目 II
两条平行线 斜率相同
平行四边形被计算了两次 去除对角线中点重合的两对平行线
python
def countTrapezoids(points):
"""
:type points: List[List[int]]
:rtype: int
"""
from collections import defaultdict
n=len(points)
slope = defaultdict(list)
mid = defaultdict(list)
ans = 0
for i in range(n):
x1,y1=points[i]
for j in range(i+1,n):
x2,y2=points[j]
dx=x1-x2
dy=y1-y2
k = float("inf")
if x1==x2:
b=x1
else:
k=(y2-y1)/(x2-x1)
b=(y1*dx-x1*dy)/dx
midv=(x1+x2)*10000+(y1+y2)
slope[k].append(b)
mid[midv].append(k)
for slist in slope.values():
if len(slist)==1:
continue
cnt = defaultdict(int)
for bv in slist:
cnt[bv]+=1
totalsum=0
for count in cnt.values():
ans+=totalsum*count
totalsum+=count
print(ans,totalsum)
for mlist in mid.values():
if len(mlist)==1:
continue
cnt=defaultdict(int)
for kv in mlist:
cnt[kv]+=1
totalsum=0
for count in cnt.values():
ans-=totalsum*count
totalsum+=count
return ans
12/4 2211. 统计道路上的碰撞次数
从左到右遍历所有车辆
tag标记左侧状态 -1为没有车或者都是左向的车
0为有停住的车
其他为向右开的车数量
python
def countCollisions(directions):
"""
:type directions: str
:rtype: int
"""
ans=0
tag=-1
for d in directions:
if d=='L':
if tag>=0:
ans += tag+1
tag=0
elif d=='S':
if tag>0:
ans+=tag
tag=0
else:
if tag>=0:
tag+=1
else:
tag=1
return ans
12/5 3432. 统计元素和差值为偶数的分区方案
差为偶数 说明左右两边和的奇偶性相同
奇偶性相同说明总和一定是偶数
只要总和为偶数 无论什么位置都满足
python
def countPartitions(nums):
"""
:type nums: List[int]
:rtype: int
"""
n=len(nums)
return n-1 if sum(nums)%2==0 else 0
12/6 3578. 统计极差最大为 K 的分割方式数
动规
dp[i]标识以下标i结尾的前缀子数组有多少方案
pre[i]为前i个下标结尾的合法方案综合
cnt记录当前数组 将当前数值放入查看是否满足
python
def countPartitions(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
from sortedcontainers import SortedList
MOD=10**9+7
n=len(nums)
dp=[0]*(n+1)
pre=[0]*(n+1)
cnt=SortedList()
dp[0]=1
pre[0]=1
j=0
for i in range(n):
cnt.add(nums[i])
while j<=i and cnt[-1]-cnt[0]>k:
cnt.remove(nums[j])
j+=1
dp[i+1]=(pre[i]-(pre[j-1] if j>0 else 0))%MOD
pre[i+1]=(pre[i]+dp[i+1])%MOD
return dp[n]
12/7
python