3.19美团笔试代码记录

考试的时候心态容易崩,甚至不知道自己到底a了几道。。。。
现在静下心来写,每道题都很简单。。。。
第一题满减or折扣,用前缀就可;
第二题加密和解密模拟操作即可;
着重记录一下第三题和第四题吧

第三题:区间覆盖

同门说暴力是可以过的,当时以为过不了,就直接空着没写了555555555
现在补一个o(nlogn)的优化版本吧。思路就是:右端点排序+栈合并区间

n, m1, m2 = map(int, input().split())
machine1l = list(map(int, input().split()))
machine1r = list(map(int, input().split()))
machine2l = list(map(int, input().split()))
machine2r = list(map(int, input().split()))

machine1 = list(zip(machine1l, machine1r))
machine2 = list(zip(machine2l, machine2r))
intervals = sorted(machine1 + machine2, key = lambda x: x[1])
ans = 0
stack = []  ## 存放互不相交的区间
for interval in intervals:
    while stack and interval[0] <= stack[-1][1]:
        preinterval = stack.pop()
        ans += preinterval[1] - max(preinterval[0], interval[0]) + 1     
        interval = [min(preinterval[0], interval[0]), interval[1]]  ##区间合并
    stack.append(interval)
print(ans)

第四题

给定n个元素的集合,从集合中选k个元素求和,使其和能被k1整除,不能被k2整除。(1 <= k <= n)
两种方法,回溯和动规,笔试的时候是用的动规
回溯法:
n ,k1, k2 = map(int, input().split())
nums = list(map(int, input().split()))
global maxsum, cnt
maxsum, cnt = float('-INF'), 0

def traceback(st, sumn, path):
    if sumn % k1 == 0 and sumn % k2 != 0:
        global maxsum, cnt
        if sumn > maxsum:
            maxsum = sumn
            cnt = 1
        elif sumn == maxsum:
            cnt += 1
    if st >= len(nums):
        return 
    for i in range(st, len(nums)):
        traceback(i+1, sumn+nums[i], path+[nums[i]])
    
traceback(0, 0, [])
print(maxsum, cnt)

动规法:dp[i][j][k] 代表到第i个球为止,选择球使得球之和 对k1余j,对k2余k且球之和最大的可选方案数量;dpsum[i][j][k] 代表到i个球为止,选择球使得球之和 对k1余j,对k2余k的方案中,球之和的最大值。
转移方程算一下就可以出来,
n ,k1, k2 = map(int, input().split())
nums = list(map(int, input().split()))
dp = [[[0]*k2 for _ in range(k1)] for _ in range(n+1)]
dpsum = [[[float('-INF')]*k2 for _ in range(k1)] for _ in range(n+1)]
dp[0][0][0] = 1
dpsum[0][0][0] = 0
for i in range(1, n+1):
    num = nums[i-1]
    for j in range(k1):
        for k in range(k2):
            c1, c2 = num%k1, num%k2
            x, y = (k1+j-c1)%k1, (k2+k-c2)%k2  ## 计算转移方程
            if dpsum[i-1][j][k] > dpsum[i-1][x][y]+num:
                dp[i][j][k] = dp[i-1][j][k]
                dpsum[i][j][k] = dpsum[i-1][j][k]
            elif dpsum[i-1][j][k] < dpsum[i-1][x][y]+num:
                dp[i][j][k] = dp[i-1][x][y]
                dpsum[i][j][k] = dpsum[i-1][x][y]+num
            else:
                dp[i][j][k] = dp[i-1][j][k] + dp[i-1][x][y]
                dpsum[i][j][k] = dpsum[i-1][j][k]
ans1, ans2 = float('-INF'), 0
ans1 = max(dpsum[n][0][1:])
ans2 = dp[n][0][dpsum[n][0][1:].index(max(dpsum[n][0][1:]))+1]
print(ans1, ans2)
嘤嘤嘤嘤嘤嘤嘤嘤嘤嘤嘤嘤嘤嘤嘤嘤嘤嘤,以后一定计时刷题⏲

#2022春招##美团##笔经#
全部评论
同样的感受,面试的时候有时太紧张,脑子就空白了
1 回复
分享
发布于 2022-03-22 16:49
老铁收到面试通知了吗
1 回复
分享
发布于 2022-03-23 00:10
联想
校招火热招聘中
官网直投
复盘果然是好的,美团二面让我重新coding了笔试最后一题🤣
点赞 回复
分享
发布于 2022-04-02 18:15

相关推荐

2 15 评论
分享
牛客网
牛客企业服务