美团笔试 美团笔试题 0823

笔试时间:2025年8月23日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题

小美有 n 个长方形,第 i 个长方形的两条边长分别为 xi,yi;小美拥有一个仅包含第一象限的平面直角坐标系;小美希望将这 n 个长方形按顺序(可以旋转)放置在 x 轴上,不允许重叠,并且每个长方形放置后的高度不超过 m,保证 max(min(xi, yi)) ≤ m;请问,在满足上述条件的前提下,小美最少需要占用 x 轴的长度是多少?

输入描述

第一行输入两个整数 n, m(1 ≤ n ≤ 2×10⁵;1 ≤ m ≤ 10⁹),分别表示长方形的个数和允许的最大高度;接下来 n 行,每行输入两个整数 xi, yi(1 ≤ xi, yi ≤ 10⁹),分别表示第 i 个长方形的两条边长。

输出描述

输出一个整数,表示在每个长方形高度不超过 m 的情况下,所需占用的最短 x 轴长度。

样例输入

3 4

1 2

2 5

4 2

样例输出

8

参考题解

对于每个长方形,其边长为 x_i 和 y_i。在放置时,我们可以选择其中一条边作为高,另一条边作为长(即在 x 轴上的投影)。我们依次处理每个长方形,并为它选择最优的放置方式,使得它在 x 轴上占用的长度尽可能短。对于第 i 个长方形,边长为 x,y:如果 x 和 y 都大于 m: 这种情况在题目中被保证不会发生(保证 max(min(x_i,y_i)) <= m),因为这确保了每个长方形至少有一条边不大于 m。如果只有一条边大于 m:假设 xm 且 yleqm。此时,我们必须选择边长 y 作为高,因为 x 作为高会超过限制。因此,这个长方形在 x 轴上占用的长度就是 x。同理,如果 ym 且 xleqm,我们必须选择边长 x 作为高,占用的 x 轴长度为 y。如果 x 和 y 都不大于 m (xleqm 且 yleqm):此时,无论用 x 还是 y 作为高,都满足条件。为了让占用的 x 轴长度最小,我们应该选择较短的那条边作为长度。因此,占用的长度为 min(x,y)。我们将每个长方形按上述规则计算出的最小长度累加起来,即可得到最终答案。

C++:

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    long long ans = 0;

    for (int i = 0; i < n; i++) {
        long long x, y;
        cin >> x >> y;

        if (x > m && y > m) {
            continue;
        } else if (x > m) {
            ans += x;
        } else if (y > m) {
            ans += y;
        } else {
            ans += min(x, y);
        }
    }

    cout << ans << "\n";
    return 0;
}

Java:

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());

        long ans = 0;
        for (int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            long x = Long.parseLong(st.nextToken());
            long y = Long.parseLong(st.nextToken());

            if (x > m && y > m) {
                // skip
            } else if (x > m) {
                ans += x;
            } else if (y > m) {
                ans += y;
            } else {
                ans += Math.min(x, y);
            }
        }

        System.out.println(ans);
    }
}

Python:

import sys

def solve():

    n, m = map(int, input().split())

    ans = 0

    for _ in range(n):
        x, y = map(int, sys.stdin.readline().split())

        if x > m and y > m:

            pass
        elif x > m:
            ans += x
        elif y > m:
            ans += y
        else:
            ans += min(x, y)

    print(ans)



solve()

第二题

需在仅依赖 numpy / pandas / scikit-learn 前提下,完成基于 DBSCAN 的异常检测器。 步骤说明 1. 读取数据:输入为含 train(二维列表,数值特征)、test(二维列表,特征维度与 train 相同,无标签,无监督场景)的 JSON 数据。 2. 预处理:将 train 与 test 按行拼接,用 StandardScaler 对所有特征做标准化(fit_transform 一次完成)。 3. DBSCAN 聚类:参数固定为 eps=0.3,min_samples=3,metric="euclidean",algorithm="auto" 进行聚类。 4. 簇标签重映射:原本标签集合为 {-1, 0, 1, ...},-1 为离群点;对非 -1 的簇,计算在标准化特征空间的质心 \(c_i\),按质心第一维坐标从小到大排序得到顺序 \(\ell_0, \ell_1, \dots\),重新赋值 \(\ell_0 \to 0\),\(\ell_1 \to 1\),…,离群点标签保持 -1 不变。 5. 结果输出:仅对 test 部分输出重新映射后的标签序列,以单行 JSON 数组输出。

输入描述

标准输入为一行 JSON,含 train、test 字段,数值为整数或浮点数,无空行。

输出描述

标准输出为一行 JSON 数组,长度等于测试样本数,逗号后有空格。

样例输入

{"train": [[0,0],[0,1,0],[5,5],[5,1.5],[5,10.0]],"test":[[0.05,0.05],[5.05,5.05],[9,0]]}

样例输出

[0, 1, -1]

参考题解

数据准备与合并 (Preparation)首先,代码读取输入的JSON数据,分离出train和test两部分。为了让所有数据点都在同一个空间中进行比较和聚类,它将train和test数据集合并。由于每个数据点的维度(向量长度)可能不同,代码会找到最长的维度,并将所有较短的数据点通过补0的方式填充到相同的长度,这被称为“Padding”。数据标准化与聚类 (Clustering)对合并后的整套数据进行标准化(StandardScaler)。这一步是为了消除不同特征(维度)之间量纲的影响,使得每个特征都能被公平地计算距离,这对DBSCAN这类依赖距离的算法至关重要。在标准化后的数据上执行核心的 DBSCAN 聚类算法,它会自动根据数据点的密度将它们划分成不同的簇,并将离群点标记为噪声(标签为-1)。标签重排序 (Reordering)这是整个代码中最关键的技巧。DBSCAN算法本身输出的簇标签(如簇0, 簇1, 簇2...)是不确定的,每次运行可能顺序不同。为了得到一个稳定且唯一的输出,代码通过以下方式对标签进行“规范化”处理:计算出每个非噪声簇的几何中心点(质心)。根据所有质心在第一个维度上的坐标值进行排序。按照这个新的排序顺序,将簇的标签重新命名为 0, 1, 2, ...。这样,无论运行多少次,空间位置最靠前的簇永远是0号,以此类推。

C++:

Java:

Python:

import json
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import DBSCAN

data = json.loads(input())
tlist = data.get('train', [])
tstlst = data.get('test', [])

ntsam = len(tlist)
full = tlist + tstlst

mxln = 0
if full:
    mxln = max(len(row) for row in full)

pdlst = []
for row in full:
    rw = row + [0] * (mxln - len(row))
    pdlst.append(rw)

fulld = np.array(pdlst, dtype=float)

sc = StandardScaler()
scdt = sc.fit_transform(fulld)

dbscan = DBSCAN(eps=0.3, min_samples=3, metric="euclidean", algorithm="auto")
labs = dbscan.fit_predict(scdt)

unqlabs = np.unique(labs)
corlabs = sorted([label for label in unqlabs if label != -1])

mpplabs = np.copy(labs)

if corlabs:
    ctrd = []
    vcorelabs = []
    for label in corlabs:
        cluster_points = scdt[labs == label]
        if cluster_points.shape[0] > 0:
            centroid = cluster_points.mean(axis=0)
            ctrd.append(centroid)
            vcorelabs.append(label)

    if ctrd:
        ctrd = np.array(ctrd)
        stdindi = np.argsort(ctrd[:, 0])

        labmpp = {-1: -1}
        for newlabs, oldlabsidx in enumerate(stdindi):
            oldlabs = vcorelabs[oldlabsidx]
            labmpp[oldlabs] = newlabs

        mpplabs = np.array([labmpp.get(label, -1) for label in labs])

ans = mpplabs[ntsam:]

print(json.dumps(ans.tolist()))

第三题

给你两个正整数(x),(y),定义一个整数如果是特别的数,那么它一定满足以下条件至少其一:

  • 它是(x)的整数倍。
  • 它是(y)的整数倍。
  • 它是(x)的因子。
  • 它是(y)的因子。

给你一个整数(n),请你求出(1 ~ n)中有多少

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

2025 春招笔试合集 文章被收录于专栏

2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务