一、第一题:鱼塘钓鱼
解题思路:多路归并+优先队列
首先枚举能走到的距离然后再用优先队列将最大的值累加
【Python程序代码】
from heapq import *
n = int(input())
a = [0] + list(map(int,input().split()))
b = [0] + list(map(int,input().split()))
l = [0,0] + list(map(int,input().split()))
for i in range(2,n+1):l[i] +=l[i-1]
t = int(input())
ans = 0
i = 1
def gt(s,j):
return s//j+1
while i<=n and t-l[i]>=0:
new_t = t - l[i]
res,hq = 0,[]
for j in range(1,i+1):
ci = gt(a[j],b[j])
for k in range(ci):
heappush(hq,-max(a[j]-k*b[j],0))
for k in range(new_t):
if hq:res -= heappop(hq)
else:break
ans = max(ans,res)
i += 1
print(ans)
二、第二题:技能升级
解题思路:多路归并+二分
对攻击力大小进行二分,ck函数是检查能否升级这么多次。
【Python程序代码】
n,m = map(int,input().split())
a,b = [],[]
for i in range(n):
a_,b_ = map(int,input().split())
a.append(a_); b.append(b_)
l,r = 0,10000000
def ck(mid):
res = 0
for i in range(n):
if a[i]<mid:continue
res += (a[i]-mid)//b[i] + 1
if res>=m:return True
return False
while l<r:
mid = (l+r+1)>>1
if ck(mid):l = mid
else:r = mid-1
cnt,res=m,0
for i in range(n):
if a[i]<r:continue
t = (a[i]-r)//b[i] +1
cnt -= t
res += (2*a[i]-(t-1)*b[i])*t//2
print(res+cnt*r)
三、第三题:谦虚的数字
解题思路: 多路归并
一个谦虚数一定是由比它小的谦虚数乘一个数得到。
【Python程序代码】
from math import *
k,n = map(int,input().split())
a = list(map(int,input().split()))
st = [0]*(k+10)
res = [1]
for _ in range(n):
ans = inf
for i in range(k):
p = res[ st[i] ]*a[i]
if p<ans:ans=p
for i in range(k):
p = res[ st[i] ]*a[i]
if p==ans:st[i]+=1
res.append(ans)
print(res[-1])
四、第四题:序列
解题思路:多路归并
两组两组之间合并,对其中一个进行排序,构造出可以多路归并的数组。
【Python程序代码】
from heapq import *
T = int(input())
def work(a,b,n):
hq,c = [],[0]*(n+5)
for i in range(n):
heappush(hq,(a[0]+b[i],0))
for i in range(n):
x,y = heappop(hq)
c[i] = x
heappush(hq,(x-a[y]+a[y+1],y+1))
for i in range(n):a[i]=c[i]
for _ in range(T):
m,n = map(int,input().split())
a = list(map(int,input().split()))
a.sort(); a = a + [0]*100
for i in range(m-1):
b = list(map(int,input().split()))
work(a,b,n)
for i in range(n):
print(a[i],end=' ')
print()