2023.04.22美团笔试

4.22的美团笔试,题比较简单,写起来像在打abc。

T1

求学分和成绩的加权平均值,照着算进行。

特判一下min{b_i}<60。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define Ve(T) vector<T>
/*
小美是个勤奋努力的大学生。小美想要获得奖学金。

小美总共修习了 n 门课程,每门课程都有一个学分 ai ,而这门课小美的成绩是 bi 。

小美所在的学校对于奖学金的评定非常简单:只要所有课程的均分不低于一个给定的标准 X,而且没有任何课程挂科,就可以申请奖学金。

均分是指所有课程的成绩按照学分加权的平均值,而一门课挂科即该课成绩低于60分。

现在小美会给你总共若干次询问,询问在每种课业情况下她能否申请奖学金。


*/
int PX(int Case)
{
  ll n, x;
  cin >> n >> x;
  Ve(int) a(n), b(n);
  for(auto &i:a) cin >> i;
  for(auto &i:b) cin >> i;
  ll s1=0, s2=0;
  for(int i=0; i<n; i++) {
    if(b[i] < 60) return cout << "No\n", 0;
    s1 += (a[i]*b[i]);
    s2 += a[i];
  }
  // s1 / s2 >= x
  // s1 >= x*s2
  ll res = s2*x;
  if(s1 >= res) return cout << "Yes\n", 0;
  else return cout << "No\n", 0;
  return 1;
}

int main()
{
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int T = 1;
  cin >> T;
  for(int t=1; t<=T; t++) {
    PX(t);
  }
  return 0;
}

T2

显然是第k大和第k小匹配,排序扫一遍。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define Ve(T) vector<T>
#define all(T) T.begin(),T.end()
/*
小美需要制作一个骰子。

与一般的六面骰子不同,小美需要的骰子总共有 n 面,而且每一面的数字也不同于一般的,这n面的数字需要分别是a1,a2,......an 。当然,骰子是一个正n面体,而且唯一合法的要求是所有相对的两面之和都需要相等,比如一个数字分别为 1,2,3,4,2,3 的六面骰子,那么上面1,下面4,前面2,后面3,左边2,右边3就是合法的方案。

因为方案可以很多,所以小美并不在乎究竟是怎么做出这样一个骰子,小美只想知道是否能做出一个合法的骰子。

当然,保证n为偶数。


*/
int PX(int Case)
{
  int n;
  cin >> n;
  Ve(int) v(n);
  for(auto &i:v) cin >> i;
  sort(all(v));
  int s = v[0] + v[n-1];
  int l=1, r=n-2;
  while(l<r) {
    if(v[l]+v[r] != s) return cout << "NO\n", 0;
    l++, r--;
  }
  cout << "YES\n";
  return 1;
}

int main()
{
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int T = 1;
  cin >> T;
  for(int t=1; t<=T; t++) {
    PX(t);
  }
  return 0;
}

T3

每种作物的价值是b_i-a_i,花费是t_i,完全背包跑一遍。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define Ve(T) vector<T>
#define all(T) T.begin(),T.end()
/*
小美最近在玩一个种田类游戏。

这个游戏的目的是赚尽可能多的钱,游戏中有 n 种作物,其中第 i 种作物从种植到作物成熟采摘需要 ti 天时间,种子买入价格为ai ,作物卖出价格为 bi(一个种子只会产出一个作物,种子可以重复购买)。 而游戏内总时间为 m 天,作物的种子种植和采摘、卖出等不耗时间,成熟之前作物没有价值。

假设小美只有一块土地(即每个时间只能有一个作物在生长),初始的钱足够多,小美想知道她最多能赚多少钱。


*/
int PX(int Case)
{
  int n, m;
  cin >> n >> m;
  Ve(int) t(n), a(n), b(n), v(n);
  for(auto &i:t) cin >> i;
  for(auto &i:a) cin >> i;
  for(auto &i:b) cin >> i;
  for(int i=0; i<n; i++) {
    v[i] = b[i] - a[i];
  }
  Ve(int) dp(m*10);
  for(int i=0; i<n; i++) {
    for(int j=t[i]; j<=m; j++) {
      dp[j] = max(dp[j], dp[j-t[i]] + v[i]);
    }
  }
  int ans = 0;
  for(int i=0; i<=m; i++) ans = max(ans, dp[i]);
  cout << ans << '\n';
  return 1;
}

int main()
{
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int T = 1;
  // cin >> T;
  for(int t=1; t<=T; t++) {
    PX(t);
  }
  return 0;
}

T4

先特判全删和不删的情况,再考虑部分保留。

枚举保留s_i,考虑前缀i-1和后缀i+1,预处理dp然后取最小。

pre_dp[i][0]:前i个前缀去掉的最小费用

pre_dp[i][1]:第i个保留的最小费用

取min(pre_dp[i-1][1],pre_dp[i-1][0])即可。

suf_dp同理。

有更短的写法,无脑dp比较显然也好写。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define Ve(T) vector<T>
#define all(T) T.begin(),T.end()
/*
小美给你一个长度为 n 的01串(仅包含字符0和1的串),你可以删除这个串的一个前缀和一个后缀(可以为空),即保留一个原串的连续子串,操作之后整个串的代价为下面两部分之和:

1. 被删除的字符1的个数;

2. 剩下的子串的字符0的个数

你需要最小化操作的代价,并将其输出。

输入仅一行,一个长度为 n 的01字符串。

对于所有数据,1≤n≤105

101110110
  111011
*/
int PX(int Case)
{
  string s;
  cin >> s;
  int n = s.size();
  Ve(int) pre_0(n+3, 0), pre_1(n+3, 0);
  for(int i=1; i<=n; i++) {
    pre_0[i] = pre_0[i-1] + (s[i-1]=='0');
    pre_1[i] = pre_1[i-1] + (s[i-1]=='1');
  }
  Ve(int) suf_0(n+3, 0), suf_1(n+3, 0);
  for(int i=n; i>0; i--) {
    suf_0[i] = suf_0[i+1] + (s[i-1]=='0');
    suf_1[i] = suf_1[i+1] + (s[i-1]=='1');
  }
  vector<vector<int>> pre_dp(n+3, Ve(int)(2, 0));
  for(int i=1; i<=n; i++) {
    pre_dp[i][0] = pre_1[i];
    pre_dp[i][1] = min(pre_dp[i-1][0], pre_dp[i-1][1]) + (s[i-1]=='0');
  }
  vector<vector<int>> suf_dp(n+3, Ve(int)(2, 0));
  for(int i=n; i>=1; i--) {
    suf_dp[i][0] = suf_1[i];
    suf_dp[i][1] = min(suf_dp[i+1][0], suf_dp[i+1][1]) + (s[i-1]=='0');
  }
  int ans = min(pre_1[n], pre_0[n]);
  for(int i=1; i<=n; i++) {
    //  保留i 考虑pre[i-1] 和 suf[i+1]
    int l = min(pre_dp[i-1][0], pre_dp[i-1][1]);
    int r = min(suf_dp[i+1][0], suf_dp[i+1][1]);
    int res = l+r + (s[i-1]=='0');
    ans = min(ans, res);
  }
  cout << ans << '\n';
  return 1;
}

int main()
{
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int T = 1;
  // cin >> T;
  for(int t=1; t<=T; t++) {
    PX(t);
  }
  return 0;
}

T5

数据很小,照着题意模拟一下就行。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define Ve(T) vector<T>
#define all(T) T.begin(),T.end()
#define pii pair<int,int>
/*
小美正在参加一个比赛。

这个比赛总共有 2k 个人参加(包括小美),编号为1,2,...,2k,开始的时候所有人都在同一个小组。比试的规程如下:假设当前小组有 n 个人(n 为偶数),那么编号大小前 n/2 人分为一个新的小组,后 n/2 人分为一个新的小组,然后两个小组内部分别比试,决出各自的胜者,然后两个小组的胜者进行比试,胜者作为当前小组的优胜者,直到决出最初的小组的优胜者。当然一个人的小组优胜者肯定是他自己。例如如果当前小组有 4 个人,编号为1,2,3,4,那么就会将 1,2 分为一组,3,4分为一组分别比试,然后 1,2 中的胜者和 3,4 中的胜者再进行比试,决出整个小组的胜者。

由于每个人的能力各不相同,小美预测了所有人两两比试时的胜者,现在小美想知道预测最终的胜者是谁。
*/
int PX(int Case)
{
  int n;
  cin >> n;
  map<pii,int> mp;
  for(int i=1; i<=(1<<n); i++) {
    for(int j=1; j<=(1<<n); j++) {
      int x;
      cin >> x;
      mp[{i, j}] = x;
    }
  }
  Ve(int) v;
  for(int i=1; i<=(1<<n); i++) v.push_back(i);
  while(v.size() > 1) {
    Ve(int) now;
    for(int i=0; i<v.size(); i+=2) {
      int l = v[i], r = v[i+1];
      now.push_back(mp[{l, r}]);
    }
    v = now;
  }
  int ans = v[0];
  cout << ans << '\n';
  return 1;
}

int main()
{
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int T = 1;
  // cin >> T;
  for(int t=1; t<=T; t++) {
    PX(t);
  }
  return 0;
}


全部评论
这就是大佬吗
2 回复 分享
发布于 2023-04-23 10:06 浙江
🐮啊
1 回复 分享
发布于 2023-04-23 11:39 上海
T4 suf_0好像没用
点赞 回复 分享
发布于 2023-04-23 11:49 广东
第五道题能通过吗,代码里面没有分组pk而是直接pk
点赞 回复 分享
发布于 2023-04-23 12:03 浙江
最后一个题我直接深度优先暴力求解也过了 ``` int dfs(const vector<vector><int>>& v, int left, int right) { if(left + 1 >= right) { return v[left][right]; } int mid = (left + right) >> 1; return v[dfs(v, left, mid - 1)][dfs(v, mid, right)]; } int main() { // freopen("C:\\Users\\Admin\\Desktop\\VScode\\c++\\file in.txt", "r", stdin); cin.tie(nullptr)->sync_with_stdio(false); int k = 0; cin >> k; int n = (int)pow(2, k); vector<int> a(n + 1, 0); vector<vector><int>> v(n + 1, vector<int>(n + 1, 1)); for(int i = 1; i <= n; i++) { a[i] = i; for(int j = 1; j <= n; j++) { cin >> v[i][j]; } } int ans = dfs(v, 1, n); cout << ans << endl; return 0; } ```</int></int></vector></int></int></vector>
点赞 回复 分享
发布于 2023-04-23 21:25 北京
我为什么没有第五题,后面是三道选择,是因为我是算法吗
点赞 回复 分享
发布于 2023-04-25 11:34 上海
想问下楼主是什么岗位呀,美团的测试开发工程师的笔试也是考编程题吗,我现在什么信息都搜不到
点赞 回复 分享
发布于 2023-04-28 17:11 北京

相关推荐

Pandaileee:校友加油我现在也只有一个保底太难了
点赞 评论 收藏
分享
shtdbb_:还不错,没有让你做了笔试再挂你
点赞 评论 收藏
分享
点赞 评论 收藏
分享
2 22 评论
分享
牛客网
牛客企业服务