美团笔试 美团笔试题 0831
笔试时间:2024年08月31日 秋招
历史笔试传送门:2023秋招笔试合集
第一题
题目:小美的姓名统计
小美写单词喜欢横着写,她记录了若干个人的名字,但是不小心加进去了一些无关的单词。一个名字单词以大写字母开头,请你帮助她统计共有多少个人的名字。
输入描述
在一行上输入一个长度为n(1<=n<=10^5) 、且由大小写字母和空格混合构成的字符串 s代表小美的全部单词,每个单词之间使用空格间隔。除此之外,保证字符串的开头与结尾字符不为空格。
输出描述
在一行上输出一个整数,代表人名的个数。
样例输入一
ABC abc Abc
样例输出一
2
样例输入二
A A c
样例输出二
2
参考题解
判断每一个字符串的首字母是否为大写即可。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
int main() {
std::string input;
std::getline(std::cin, input);
std::stringstream ss(input);
std::string word;
std::vector<std::string> names;
while (ss >> word) {
names.push_back(word);
}
int cnt = 0;
for (const auto& name : names) {
if (isupper(name[0])) cnt++;
}
std::cout << cnt << std::endl;
return 0;
}
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] names = input.split("\\s+");
int cnt = 0;
for (String name : names) {
if (Character.isUpperCase(name.charAt(0))) {
cnt++;
}
}
System.out.println(cnt);
scanner.close();
}
}
Python:[此代码未进行大量数据的测试,仅供参考]
names = [c for c in input().split()] cnt = 0 for name in names: if name[0].isupper(): cnt+=1 print(cnt)
第二题
题目:小美种树(二)
长度无限长的公路上,小美雇佣了 n 位工人来种树,每个点最多种一棵树。从左向右数,工人所站的位置为 a1,a2,...,an 。已知每位工人都会将自己所在位置的右侧一段长度的区间种满树,且每位工人的种树区间长度相同。现在小美希望公路上至少有 k棵树,为了节约成本,他希望每位工人种树的区间长度尽可能短,请你帮他求出,工人们的种树区间至少多长,才能使得公路被种上至少 k棵树。
输入描述
第一行输入两个正整数 n,k(1<=n,k<=2*10^5),分别表示工人的数量,以及小美要求树的最少数量。
第二行输入 n个正整数 a1,a2,...,an(1<=ai<=2*10^5),表示每名工人的位置。
输出描述
在一行上输出一个整数,代表工人们最短的种树区间长度。
样例输入
3 6
1 2 5
样例输出
3
说明
每位工人种树的区间长度至少为 3。
这样以来:
第一名工人种:1,2,3 点的树。
第二名工人种:2,3,4 点的树。
第三名工人种:5,6,7点的树。
由于每个位置最多种一棵树,因此共有:1,2,3,4,5,6,7 这些点有树,满足至少 k=6棵树。
可以证明,不存在比 3 更小的答案。
参考题解
二分答案。我们来二分枚举每个人种树的区间,用一个check函数来判断种树的区间为x的适合,是否可以种k棵树?首先将数组进行排序,对于每一个人可以种的树的逻辑是:尽量往后种,在不超过之前的覆盖的前提下。bd记录的是上一次种到的边界,当前可以种的边界应该是 a+x,只要保证不会超过边界即可。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 判断是否可以在给定的间隔范围内种下至少 k 棵树
bool check(const vector<int>& A, int x, int k) {
int cnt = 0;
int bd = 0; // 上一次种到的边界
for (int a : A) {
if (a + x > max(a, bd)) {
cnt += (a + x) - max(a, bd);
}
bd = max(a + x, bd);
}
return cnt >= k;
}
int main() {
int n, k;
cin >> n >> k;
vector<int> A(n);
for (int i = 0; i < n; ++i) {
cin >> A[i];
}
sort(A.begin(), A.end());
int l = 0, r = 3 * 100000; // C++ 中使用更简洁的范围
while (l < r) {
int mid = (l + r) >> 1;
if (check(A, mid, k)) {
r = mid;
} else {
l = mid + 1;
}
}
cout << r << endl;
return 0;
}
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.Arrays;
import java.util.Scanner;
public class Main {
/
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
持续收录字节、腾讯、阿里、美团、美团、拼多多、华为等笔试题解,包含python、C++、Java多种语言版本,持续更新中。


