【2022-08-13】美团秋招笔试四道编程题

恭喜发现宝藏!搜索公众号【TechGuide】回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经。
作者@TechGuide【全网同名】
点赞再看,养成习惯,您动动手指对原创作者意义非凡🤝

第一题:魔法外卖

题目

有给你一系列截止时间和每次送快递需要的时间,需要在时间前把快递送过去,你有超能力可以把快递送达不需要耗费时间,问你至少需要使用几次超能力。

思路

对时间分段,比如送一个外卖需要5分钟,那么(0,5] 之内只能送一单,多余的就要用魔法,同理(5,10]时间段内也只能送一单,注意题目没说是有序数组!

代码

Python版本
arr = [100, 101, 102, 103, 104, 105]
t = 5
arr.sort()
magic = 0
cur_time = 0
for order in arr:
    if order-t>=cur_time:
        cur_time += t
    else:
        magic += 1
print(magic)
// vx公众号关注TechGuide 实时题库 闪电速递
CPP版本
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main(){
    int n,t;
    cin>>n>>t;
    vector<int>vec(n);
    for(int i=0;i<n;++i){
        cin>>vec[i];
    }
    sort(vec.begin(),vec.end());
    int res = 0;
    int cur = t;
    for(int i=0;i<n;++i){
        if(vec[i]<cur){
            ++res;
        }
        else{
            cur+=t;
        }
    }
    cout<<res<<endl;
    return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递
Java版本
public class Main
{
    public static void main(String args[])
    {
        Scanner cin = new Scanner(System.in);
        String[] line = cin.nextLine().split(" ");
        int n = Integer.parseInt(line[0]), t = Integer.parseInt(line[1]);
        int[] delivery = Arrays.stream(cin.nextLine().split(" ")).mapToInt(Integer::valueOf).toArray();
        int count = 0, time = 0;
        Arrays.sort(delivery);
        for (int i = 0; i < n; i++) {
            if (time + t <= delivery[i]){
                time += t;
            } else {
                count++;
            }
        }
        System.out.printf("%d", count);
    }
}
// vx公众号关注TechGuide 实时题库 闪电速递

第二题:打扫房间

题目:

有一个扫地机器人,和一个n*m的房子输入一串指令控制机器人上下左右走,问机器人可以打扫完房子吗,可以输出个yes和指令执行到的位置,不可以输出no和还剩几处没有打扫。

思路

这里注意题目中说了只能在矩阵内运动,所以要判断越界的情况,题目中已经明确机器人只会在区域内运动,所以可以去掉越界判断也能AC
PS:这个题目很多hxd都是多存了一个boolean[][] 判断是否被打扫过,其实我一开始也是这样想的,但后来觉得要判断是否打扫完所有区域要对m*n进行检查复杂度比较高(也看到有hxd维护了一个已经清扫过区域的变量),所以就想到先用Set进行存储了。

代码

Java版本
    public static void main2(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();
        String str = in.next();
        
        // 保存还没有被打扫过的区域下标
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                set.add(i * m + j);
            }
        }
// vx公众号关注TechGuide 获取完整题解

第三题:扑克

题目描述:

Alice和Bob在玩一个游戏。有n张卡牌,点数分别为1到n。进行洗牌后,n张牌从上到下叠放形成一个牌堆。每次Alice先将当前牌堆顶的一张牌放到牌堆底,然后Bob再将当前牌堆顶的一张牌放到牌堆底。(特别地,当牌堆中只有一张牌时,相当于不进行任何操作)接着,他们会翻开当前牌堆顶的牌,并记下它的点数。当所有牌都被翻开后,他们也记下了n个点数。现在他们想根据记下的这个序列来还原一开始的牌(从牌堆顶到牌堆底每一张牌的点数)。

输入描述

第一行是一个正整数n,表示有n张牌。
接下来一行n个用空格隔开的正整数,第i个数a_i表示第i张被翻开的牌的点数。
1<=n<=100000
输出描述
一行n个用空格隔开的正整数,第i个数表示初始牌堆中从牌堆顶到牌堆底的第i张牌的点数。
样例输入

4
1 2 3 4
样例输出
4 2 1 3

提示

初始牌堆为:4 2 1 3

  1. Alice和Bob分别操作后牌堆为:1 3 4 2,此时1被翻开,牌堆变为3 4 2
  2. Alice和Bob分别操作后牌堆为:2 3 4,此时2被翻开,牌堆变为3 4
  3. Alice和Bob分别操作后牌堆为:3 4,此时3被翻开,牌堆变为4
  4. Alice和Bob分别操作后牌堆依旧为4,此时4被翻开。

思路

用双向队列的 简单模拟
牌堆可以使用双向队列模拟。每轮从牌堆顶抽一张牌,再放入牌堆底。这个动作可以抽象为从队列头取出一个元素,再放入队尾。
我们使用origin数组模拟初始牌堆中每张牌的顺序和每张牌的牌点的关系。

代码

Python版本
n = int(input())
nums = [x for x in input().split()]
import collections
def solver(nums):
    n = len(nums)
    if n == 1 or n == 2:
        return " ".join(nums)
    ans = collections.deque(list(range(n)))
// vx公众号关注TechGuide 获取完整题解

第四题:合法元组数

题目:

求三元组,满足i<j<k&&nums【i】-2nums【j】=2*nums【j】-nums【k】

思路

LeetCode经典三数之和改编版。唯一的坑是最后的三元组很多,用int会溢出。

代码

Java版本
public class Main
{
    public static void main(String args[])
    {
        Scanner cin = new Scanner(System.in);
        int n =  Integer.parseInt(cin.nextLine());
        int[] nums = Arrays.stream(cin.nextLine().split(" ")).mapToInt(Integer::valueOf).toArray();
        long count = 0;
        Map<Integer, Integer> mp = new HashMap<>();
        mp.put(nums[n - 1], 1);
        for (int i = n - 2; i >= 1; i--) {
            for (int j = i - 1; j >= 0; j--) {
                count += mp.getOrDefault(3 * nums[i] - nums[j], 0);
// vx公众号关注TechGuide 获取完整题解

第五题:生活在树上

题目

路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给定一个二叉树的根节点 root ,返回其 最大路径和,即所有路径上节点值之和的最大值。

思路

LeetCode经典 三角形最小路径。 不用care是不是叶子。因为叶子的累计的值一定比非叶子大

代码

Java版本
public class Main
{
    public static void main(String args[])
    {
        Scanner cin = new Scanner(System.in);
        int n =  Integer.parseInt(cin.nextLine());
        String[] _nums = cin.nextLine().split(" ");
        int[] nums = new int[n + 1];
        for (int i = 1; i <= n; i++) nums[i] = Integer.parseInt(_nums[i - 1]);
        int ans = 0;
        Queue<Integer> q = new ArrayDeque<>();
        q.offer(1);
        while (!q.isEmpty()) {
// vx公众号关注TechGuide 获取完整题解
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值