【美团0325】春招实习笔试练习

五道题都不难

1. 火车迷

题目描述:

小美是一个火车迷。最近她在观察家附近火车站的火车驶入和驶出情况,发现火车驶入和驶出的顺序并不一致。经过小美调查发现,原来这个火车站里面有一个类似于栈的结构,如下图所示:

例如可能1号火车驶入了火车站中的休息区s,在驶出之前2号火车驶入了。那么在这种情况下,1号火车需要等待2号火车倒车出去后才能出去(显然被后面驶入的2号火车挡住了,这个休息区s只有一个出入口)。出于好奇,小美统计了近些天的火车驶入驶出情况,开始统计和结束统计时休息区s中均是空的。由于中途疏忽,小美觉得自己好像弄错了几个驶入驶出顺序,想请你帮她验证一下。值得注意的是,小美虽然可能弄错了顺序,但对火车的记录是不重不漏的。形式化地来形容休息区s,我们视其为一个容量无限大的空间,假设两列火车 i 和 j 同时处于休息区s中,驶入时刻Tin满足Tin(i)<Tin(j),则驶出时间Tout必定满足Tout(i)>Tout(j),即,先进后出。

输入描述:

第一行一个整数T表示数据组数。

对每组测试而言:

第一行一个整数n,表示观察到的火车数量。

第二行n个整数x1,x2,...,xn,表示小美记录的火车驶入休息区s的顺序。

第三行n个整数y1,y2,...,yn,表示小美记录的火车驶出休息区s的顺序。

1≤T≤10,1≤n≤50000,1≤xi,yi≤n, 且{xn} 、{yn} 均为{1,2,3,...,n}的一个排列,即1~n这n个数在其中不重不漏恰好出现一次。

输出描述:

对每组数据输出一行:如果小美记录的驶入和驶出顺序无法被满足则输出No,否则输出Yes。

样例输入:

3
3
1 2 3
1 2 3
3
1 2 3
3 2 1
3
1 2 3
3 1 2

样例输出:

Yes
Yes
No

思路:栈模拟,打卡题。

#include <iostream>
#include <vector>
#include <stack>
using namespace std;

int main() {
	int T; cin >> T;
	for (int i = 0; i < T; i++) {
		int n; cin >> n;
		vector<int> inS(n);
		for (int j = 0; j < n; j++) {
			cin >> inS[j];
		}
		vector<int> outS(n);
		for (int j = 0; j < n; j++) {
			cin >> outS[j];
		}
		stack<int> s;
		int p = 0;
		bool flag = true;
		for (int j = 0; j < n; j++) {
			int temp = outS[j];
			if (s.empty()) {
				while (p < n && inS[p] != temp) {
					s.push(inS[p]);
					p++;
				}
				if (p == n) {
					flag = false;
					break;
				}
			}
			else {
				if (s.top() == temp) {
					s.pop();
				}
				else {
					while (p < n && inS[p] != temp) {
						s.push(inS[p]);
						p++;
					}
					if (p == n) {
						flag = false;
						break;
					}
				}
			}
		}
		if (flag) {
			cout << "YES" << endl;
		}
		else {
			cout << "NO" << endl;
		}
	}
	return 0;
}

2. 分糖

题目描述:

小美因乐于助人的突出表现获得了老师的嘉奖。老师允许小美从一堆n个编号分别为1,2,...,n的糖果中选择任意多个糖果作为奖励(每种编号的糖果各一个),但为了防止小美一次吃太多糖果有害身体健康,老师设定了一个限制:如果选择了编号为 i 的糖果,那么就不能选择编号为 i-1, i-2, i+1, i+2的四个糖果了。在小美看来,每个糖果都有一个对应的美味值,小美想让她选出的糖果的美味值之和最大!作为小美的好朋友,请你帮帮她!

输入描述:

第一行一个整数n,表示糖果数量。

第二行n个整数a1,a2,...,an,其中ai表示编号为 i 的糖果的美味值。

1≤n≤50000 , 1≤ai≤10000

输出描述:

输出一行一个数,表示小美能获得的糖果美味值之和最大值。

样例输入:

7
3 1 2 7 10 2 4

样例输出:

14

思路:常规dp

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;

int main() {
	int n; cin >> n;
	vector<int> candy(n);
	for (int i = 0; i < n; i++) {
		cin >> candy[i];
	}
	vector<int> dp(n);
	dp[0] = candy[0];
	for (int i = 1; i < n; i++) {
		for (int j = 3; j <= 5; j++) {
			if (i - j < 0)	break;
			dp[i] = max(candy[i] + dp[i - j], dp[i]);
		}
	}
	cout << dp[n - 1];
	return 0;
}

3. 春游

题目描述:

小美明天要去春游了。她非常喜欢吃巧克力,希望能够带尽可能多的巧克力在春游的路上吃。她现在有n个巧克力,很巧的是她所有的巧克力都是厚度一样的正方形的巧克力板,这n个巧克力板的边长分别为a1,a2,...,an。因为都是厚度一致的正方形巧克力板,我们认为第 i 个巧克力的重量为a_i^2​。小美现在准备挑选一个合适大小的包来装尽可能多的巧克力板,她十分需要你的帮助来在明天之前准备完成,请你帮帮她。

输入描述:

第一行两个整数n和m,表示小美的巧克力数量和小美的询问数量。
第二行n个整数a1,a2,...,an,表示n块正方形巧克力板的边长。注意你不能将巧克力板进行拆分。
第三行m个整数q1,q2,...,qm,第 i 个整数qi表示询问:如果小美选择一个能装qi重量的包,最多能装多少块巧克力板?(不考虑体积影响,我们认为只要质量满足要求,巧克力板总能塞进包里)
1≤n,m≤50000,1≤ai≤104,1≤qi≤1018

输出描述:

输出一行m个整数,分别表示每次询问的答案。

样例输入:

5 5 
1 2 2 4 5 
1 3 7 9 15

样例输出:

1 1 2 3 3

思路:贪心(前缀和+二分)

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;

int main() {
	int n, m; cin >> n >> m;
	vector<long long> temp(n);
	for (int i = 0; i < n; i++) {
		cin >> temp[i];
	}
	sort(temp.begin(), temp.end());
	vector<long long> chocolate(n);
	chocolate[0] = temp[0] * temp[0];
	for (int i = 1; i < n; i++) {
		chocolate[i] = chocolate[i - 1] + temp[i] * temp[i];
	}
	for (int i = 0; i < m; i++) {
		int size; cin >> size;
		int l = 0, r = n - 1;
		int mid;
		while (l < r) {
			mid = (l + r + 1) >> 1;
			if (chocolate[mid] > size)	r = mid - 1;
			else l = mid;
		}
		cout << r + 1 << endl;
	}
	return 0;
}

4. 解释器

题目描述:

小美因为自己差劲的表达能力而苦恼,小美想制作一个解释器,这样她可以在无法表达的情况下让解释器帮她解释。好巧不巧小美翻开了编译原理的书,找到了解释器的制作方式,她决定先制作一个书上习题中描述的小小解释器试试。

小美需要读入一行字符串,其格式为"key1=val1; key2=val2; ...; keyn-1=valn-1; keyn=valn;"(不包含引号)这样的n对key,value对,其中keyi和vali为第 i 对key,value对,且均为仅包含大小写英文字母、数字与斜杠的非空字符串。例如对于字符串"SHELL=/bin/bash;HOME=/home/xiaomei;LOGNAME=xiaomei;",那么其中包含三对key,value对,以(key,value)形式展示,分别为(SHELL,/bin/bash)、(HOME,/home/xiaomei)、(LOGNAME,xiaomei)。

接下来,小美的解释器需要接受q次询问,每次询问给出一个仅包含大小写英文字母、数字与斜杠的非空字符串,如果存在某对key,value对的key值与之相同,那么输出对应的value;如果存在多对key,value对的key值与之相同,那么输出其中编号最大的,也即最后那一对的value值;如果一对也不存在,那么输出EMPTY。

输入描述:

第一行一个字符串S,满足题中所述格式。
接下来一个整数q,表示有q个询问。
接下来q行,每行一个仅包含大小写英文字母、数字与斜杠的非空字符串,分别为S1,S2,...,Sq,依次表示q次询问。
令|S|表示字符串S的长度。

S中至少包含一对key,value对。

输出描述:

输出q行,每行一个字符串表示答案。

样例输入:

LOGNAME=default;SHELL=/bin/bash;HOME=/home/xiaomei;LOGNAME=xiaomei;
4
SHELL
HOME
LOGNAME
logname

样例输出:

/bin/bash
/home/xiaomei
xiaomei
EMPTY

思路:模拟+hash

#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
using namespace std;

int main() {
	string s;cin >> s;
	int p = 0;
	unordered_map<string, string> hash_map;
	while (p < s.size()) {
		string key;
		while (s[p] != '=') {
			key += s[p];
			p++;
		}
		p++;
		string value;
		while (s[p] != ';') {
			value += s[p];
			p++;
		}
		hash_map[key] = value;
		p++;
	}
	int q; cin >> q;
	for (int i = 0; i < q; i++) {
		string temp;
		cin >> temp;
		if (hash_map[temp].size() == 0) {
			cout << "EMPTY" << endl;
		}
		else {
			cout << hash_map[temp] << endl;
		}
	}
	return 0;
}

5. 糖果盛宴

题目描述:

小美特别爱吃糖果。小美家楼下正好有一个糖果专卖店,每天供应不同种类的糖果。小美预先拿到了糖果专卖店接下来n天的进货计划表,并针对每天的糖果种类标注好了对小美而言的美味值。小美当然想每天都能去买糖果吃,不过由于零花钱限制(小美零花钱并不多!)以及健康考虑,小美决定原则上如果今天吃了,那么明天就不能吃。但小美认为凡事都有例外,所以她给了自己k次机会,在昨天已经吃了糖果的情况下,今天仍然连续吃糖果!简单来说,小美每天只能吃一次糖果,原则上如果昨天吃了糖果那么今天就不能吃,但有最多k次机会打破这一原则。小美不想浪费每次吃糖果的机会,所以请你帮帮她规划一下她的吃糖果计划,使得她能吃到的糖果美味值最大。

输入描述:

第一行两个整数n和k,表示拿到的进货计划表的天数和最多打破原则的次数。
第二行n个整数a1,a2,...,an,其中ai表示接下来第 i 天糖果专卖店的糖果的美味值。
1≤n≤2000,1≤k≤1000,1≤ai≤10000

输出描述:

输出一行一个数,表示小美能吃到的糖果美味值之和最大值。

样例输入:

7 1
1 2 3 4 5 6 7

样例输出:

19

思路:二维dp

#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
using namespace std;

int main() {
	int n, k; cin >> n >> k;
	vector<int> candy(n);
	for (int i = 0; i < n; i++) {
		cin >> candy[i];
	}
	vector<vector<int>> dp(n, vector<int>(k + 1, 0));
	dp[0][0] = candy[0];
	for (int i = 1; i < n; i++) {
		for (int j = 0; j < k; j++) {
			dp[i][j] = max(dp[i][j], candy[i]);
			//不打破原则
			if (i >= 2) {
				dp[i][j] = max(dp[i][j], dp[i - 2][j] + candy[i]);
			}
			if (i >= 3) {
				dp[i][j] = max(dp[i][j], dp[i - 3][j] + candy[i]);
			}

			//打破原则
			dp[i][j + 1] = max(dp[i][j + 1], dp[i - 1][j] + candy[i]);
		}
	}
	cout << dp[n - 1][k];
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值