美团笔试

1.模拟题,分别对RBG每个位置往左往右找即可。

2.凑颜色,直接二分答案,因为是无环转换,因此可以直接从a转换到b,再从b转换到c。

using ll = long long;
void solve() {
	int a, b, c;
	int x, y;
	cin >> a >> b >> c;
	cin >> x >> y;

	auto check = [&](int k) {
		ll reta = a, retb = b, retc = c;
		ll resa = max(0ll, reta - k);
		retb += resa / x;
		ll resb = max(0ll, retb - k);
		retc += resb / y;
		return min({reta, retb, retc}) >= k;
	};

	int l = 0, r = (int)1e9;
	while (l <= r) {
		int m = (l + r) >> 1;
		if (check(m)) {
			l = m + 1;
		} else {
			r = m - 1;
		}
	}
	cout << l - 1 << '\n';
}

3.

题目描述:

输入n q x y(定义权值数组为a),表示有n个点,q个询问,如果a[nxt[i]] > a[i],则+x, 否则+y, x和y可能是负数,

第二行输入nxt数组,表示i->nxt[i]有一条边

然后第三行输入权值数组a

接下来又q(1e5)个询问,每个询问给出ui和ki表示从ui起始最多跳ki步能取得的最大和是多少?

1<=ui<=n 1<=ki<=1e9

解题思路:考虑k太大不可能直接去模拟每一步,因此我们只需要考虑贡献的计算。

考虑把k按2进制拆分,这样去算贡献,然后合并,那么这个问题就变成了从每个点开始走(2^j)-1步能取得的最大和是多少?

这个我们考虑st表构建的过程,比较类似,也是贡献合并,因此我们的状态就设计出来了。

定义

f[i][j]:i这个点跳2^j - 1步到哪?

g[i][j]: i这个点跳2^j-1步最大贡献是多少?

比较显然的是f[i][j]的转移

f[i][j] = f[f[i][j - 1][j - 1]

接下来是考虑维护g[i][j],考虑合并两个节点时,最大贡献有什么情况呢?

1.可能原本就是左节点的答案

2.可能是原本左节点的和+右节点的靠左端的最大值和

那么我们把g[i][j]的最大值维护就想明白了。

我们需要同时维护左端最大和,该节点的总和,该节点的答案。

代码实现:

using ll = long long;
const int N = 2e5 + 5;
const int B = 31;

int f[N][B];
struct Node {
	ll lmx, tmx;
	ll s;
}g[N][B];

void solve() {
	int n, q;
	int x, y;
	cin >> n >> q;
	cin >> x >> y;

	vector<int> nxt(n + 1), a(n + 1);
	for (int i = 1; i <= n; i++) {
		cin >> nxt[i];
	}

	auto merge = [&](Node &lhs, Node &rhs) {
		Node t;
		t.tmx = lhs.tmx;
		t.lmx = max(lhs.lmx, lhs.s + rhs.lmx);
		t.tmx = max(t.tmx, t.lmx);
		t.s = lhs.s + rhs.s;
		return t;
	};
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}

	for (int i = 1; i <= n; i++) {
		f[i][0] = nxt[i];
		if (a[nxt[i]] > a[i]) {
			Node gt;
			gt.lmx = x;
			gt.tmx = x;
			gt.s = x;
			g[i][0] = gt;
		} else {
			Node gt;
			gt.lmx = y;
			gt.tmx = y;
			gt.s = y;
			g[i][0] = gt;
		}
	}
	for (int i = 1; i <= 30; i++) {
		for (int j = 1; j <= n; j++) {
			g[j][i] = merge(g[j][i - 1], g[f[j][i - 1]][i - 1]);
			f[j][i] = f[f[j][i - 1]][i - 1];
		}
	}

	auto query = [&](int u, int k) {
		Node t = {0, 0, 0};
		ll ret = 0;

		for (int i = 30; i >= 0; i--) {
			if (k >> i & 1) {
				t = merge(t, g[u][i]);
				u = f[u][i];
			}
			ret = max(ret, t.tmx);
		}
		return ret;
	};
	while (q--) {
		int u, k;
		cin >> u >> k;
		cout << query(u, k) << '\n';
	}
}

#美团##美团笔试#
全部评论
感谢大佬
1 回复 分享
发布于 09-15 14:11 北京
第二题是怎么想到二分的呀,没想到用二分...
1 回复 分享
发布于 09-15 19:21 湖南
凯哥tql
点赞 回复 分享
发布于 09-15 10:22 湖南

相关推荐

点赞 评论 收藏
分享
时间:9-2&nbsp;&nbsp;16:00-17:151、简单自我介绍2、项目细节深挖(黑马点评项目,对细节还没有熟透,一通乱答,全是破绽,挖了接近半个小时)3、java基础:hashcode和equal方法是哪个类里面的(Object类,紧张了答了个Project类,被说没这个类,才说了Objec类),两者区别(好久没背javase,跟面试官墨迹了好一会才答上来),==和equals区别,arraylist和linkedlist区别以及增删改查时间复杂度(一个动态数组、一个双向链表,时间复杂度按着答了下,问题不大)4、JVM:常见垃圾回收器(没记住太多,答了个Serial,G1),垃圾回收算法(面试前刚背的,流利吟唱:标记清除、复制、标记整理)5、Spring:对Spring了解多少,答只会用,对底层不熟,没往下问,问IOC了解吗(简单答了个控制反转,解耦合)6、线程:线程池了解吗?(答为了解决线程频繁创建和销毁导致资源浪费),线程池创建要哪些参数(核心线程数、最大线程数、空闲时间、时间单位、工作队列、工厂,详细解释了各个参数意义)7、MySQL索引有哪些(答哈希索引、b索引、b+索引,简单介绍了下三者结构),为什么要有索引(答提高查询效率),事务的四大特性(原子、一致、隔离、持久),怎么实现持久(不知道,乱答,说知道redis持久化是把内存存到磁盘,MySQL应该差不多)8、redis:缓存穿透、雪崩、击穿(基础、秒了)9、maven:(只知道管理项目生命周期,没细问)10、算法题:简单链表题(123456转成162534,用hashmap存储链表和序号,秒了)总结:项目还得再细看一遍,javase好久没看还得稍微看看,零实习,非科班,希望能过
查看7道真题和解析
点赞 评论 收藏
分享
1 4 评论
分享
牛客网
牛客企业服务