2022年3月5日美团笔试题题解

第一题:

/*
 * 给你一个可重集合,让你选出一个子集,使得任意两个数不连续,求最大的子集大小。
 */
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;

int n, a[N], dp[N];

int main() {
    scanf("%d", &n);
    for (int i = 1 ; i <= n ; i ++) scanf("%d", &a[i]);
    sort(a + 1, a + n + 1);
    int m = unique(a + 1, a + n + 1) - a;
    dp[0] = 0, dp[1] = 1;
    for (int i = 2 ; i <= m ; i ++) {
        dp[i] = dp[i - 1]; // 不选这个数
        if (a[i] > a[i - 1] + 1) {
            dp[i] = max(dp[i], dp[i - 1] + 1); // 尝试把当前这个数加入到 i-1
        }
        dp[i] = max(dp[i], dp[i - 2] + 1);
    }
    int ans = 0;
    for (int i = 1 ; i <= m ; i ++) ans = max(ans, dp[i]);
    cout << ans << endl;
    return 0;
}

第二题:

/*
 * 给你一个数组,可以对数组在任意位置翻转一次,也可以不翻转,让你求出最大连续和。
 */
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;

int n, a[N], sum[N], mx[N], mval[N];

int main() {
    scanf("%d", &n);
    for (int i = 1 ; i <= n ; i ++)
        scanf("%d", &a[i]), sum[i] = sum[i - 1] + a[i];
    int ans = 0;
    for (int i = 1, s = 0 ; i <= n ; i ++) {
        s += a[i];
        if (s < 0) s = 0; // 求 1~i 的最大连续和
        mx[i] = max(mx[i - 1], s); // 最大连续和的前缀最大值
        mval[i] = max(mval[i - 1], mx[i] - sum[i]);
        ans = max(ans, sum[i] + mval[i - 1]);
    }
    cout << ans << "\n";
    return 0;
}

第三题:

/*
 * 给你一个边长为n的正方体,然后每次操作是对x,y,z轴的其中一个轴进行切割,切割的位置是距离左边为d的位置
 * 求出每次切割后的最大体积块
 */
#include <bits/stdc++.h>
using namespace std;

const int N = 1005;

int n, m, d[N];
char op[N];
int v[3][N], tot[3], mx[3];

int main() {
    cin >> n >> m;
    for (int i = 1 ; i <= m ; i ++) cin >> op[i];
    for (int i = 1 ; i <= m ; i ++) cin >> d[i];
    for (int i = 0 ; i < 3 ; i ++) tot[i] = 1, v[i][1] = mx[i] = n;
    for (int t = 1 ; t <= m ; t ++) {
        int id = op[t] - 'x';
        int idx = -1, L = -1, R = -1;
        for (int i = 1, l = 0 ; i <= tot[id] ; i ++) {
            int r = l + v[id][i];
            if (r > d[i]) {
                idx = i, L = d[i] - l, R = r - d[i];
                break;
            }
            l += v[id][i];
        }         tot[id] ++;         for (int i = tot[id] ; i > idx ; i --) v[id][i] = v[id][i - 1];         // idx, idx + 1         v[id][idx] = L;         v[id][idx + 1] = R;         mx[id] = 0;         for (int i = 1 ; i <= tot[id] ; i ++) mx[id] = max(mx[id], v[id][i]);         cout << mx[0] * mx[1] * mx[2] << endl;     }     return 0; }

第四题:

#include <bits/stdc++.h>
using namespace std;
#define ls (rt << 1)
#define rs (rt << 1 | 1)
const int N = 5005;

int n, a[N], cnt[N], tag[N];
LL sum[N << 2], add[N << 2];

void pushup(int rt) {
	sum[rt] = sum[ls] + sum[rs];
}

void pushdown(int rt, int l, int r) {
	if (add[rt]) {
		int mid = (l + r) >> 1;
		sum[ls] += add[rt] * (mid - l + 1);
		sum[rs] += add[rt] * (r - mid);
		add[ls] += add[rt], add[rs] += add[rt];
		add[rt] = 0;
	}
}

void update(int rt, int l, int r, int ql, int qr, int x) {
	if (l == ql && qr == r) {
		sum[rt] += 1LL * x * (r - l + 1);
		add[rt] += x;
		return ;
	}
	pushdown(rt, l, r);
	int mid = (l + r) >> 1;
	if (qr <= mid) update(ls, l, mid, ql, qr, x);
	else if (ql > mid) update(rs, mid + 1, r, ql, qr, x);
	else update(ls, l, mid, ql, mid, x), update(rs, mid + 1, r, mid + 1, qr, x);
	pushup(rt);
}

LL query(int rt, int l, int r, int ql, int qr, int x) {
	if (l == ql && qr == r) return sum[rt];
	pushdown(rt, l, r);
	int mid = (l + r) >> 1;
	if (qr <= mid) return query(ls, l, mid, ql, qr);
	else if (ql > mid) return query(rs, mid + 1, r, ql, qr);
	else return query(ls, l, mid, ql, mid) + query(rs, mid + 1, r, mid + 1, qr);
}

int main() {
	cin >> n;
	for (int i = 1 ; i <= n ; i ++) cin >> a[i];
	LL ans = 0;
	for (int i = 1 ; i <= m ; i ++) {
		int op, l, r, k; cin >> op >> l >> r;
		if (op == 1) {
			tag[l] ++, tag[r + 1] --;
			ans += query(1, 1, n, l, r);
		} else if (op == 2) {
			cin >> k;
			update(1, 1, n, l, r, k);
		}
	}
	for (int i = 1 ; i <= n ; i ++) cnt[i] = cnt[i - 1] + tag[i];
	sort(cnt + 1, cnt + n + 1);
	sort(a + 1, a + n + 1);
	for (int i = 1 ; i <= n ; i ++) ans += 1LL * cnt[i] * a[i];
	cout << ans << "\n";
    return 0;
}

第五题:

/*
 * 给你 m 个数字以及对应的 a 和 b
 * a 是猜的数字和这个数需要有 a 个位置相同的数,b 是两个数字都包含 b 个相同的数字,但这些数字所在的位置不相同
 * 让你选出一个最小的符合条件的数字,如果不存在这个数字,则输出一个"?"
 */
#include <bits/stdc++.h>
using namespace std;

const int N = 1005;

struct node {
    string s;
    int a, b;
} v[N];
int n, m, ok, use[10];
string path, ans = "?";

void check() {  if (ok) return ;
    vector<int> pa(10, -1);
    for (int i = 0 ; i < n ; i ++) pa[path[i] - '0'] = i;
    for (int i = 1 ; i <= m ; i ++) {
        vector<int> pb(10, -1);
        for (int j = 0 ; j < n ; j ++) pb[v[i].s[j] - '0'] = j;
        int a = 0, b = 0;
        for (int j = 0 ; j < 10 ; j ++) {
            if (pa[j] != -1 && pb[j] != -1) {
                if (pa[j] == pb[j]) a ++;
                else b ++;
            }
        }
        if (v[i].a != a || v[i].b != b) return ;
    }
    if (ans == "?") ans = path, ok = 1;
}

void dfs(int x) {
    if (x > n) { check(); return ; }
    if (ok) return ;
    for (int i = 0 ; i <= 9 ; i ++) {
        if (use[i]) continue;
        path.push_back(i + '0');
        use[i] = 1;
        dfs(x + 1);
        use[i] = 0;
        path.pop_back();
    }
}

int main() {
    cin >> n >> m;
    for (int i = 1 ; i <= m ; i ++) cin >> v[i].s >> v[i].a >> v[i].b;
    dfs(1);
    cout << ans << "\n";
    return 0;
}    
  





#美团笔试##笔经##美团#
全部评论
天哪,你是都做出来了是吗
点赞 回复 分享
发布于 2022-03-06 19:46
第四题n和m太小了不用线段树直接for过去也行
点赞 回复 分享
发布于 2022-03-06 03:04
楼主是ak了吗?
点赞 回复 分享
发布于 2022-03-06 01:15

相关推荐

03-31 18:02
门头沟学院 Java
白日梦想家_等打包版:不要的哦佛给我
点赞 评论 收藏
分享
评论
14
59
分享

创作者周榜

更多
牛客网
牛客企业服务