2022美团校招技术岗笔试全部AC

2022美团校招技术岗笔试全部AC,第1张

【自动车class="superseo">class="superseo">算法岗】差了5秒钟,终究还是没能AK呀。第三题一开始只对了18%的数据,在还有20分钟的时候,发现题目看错了,码到 cout<

笔试题分为两大部分:4道算法题+3道人工智能相关知识的多选题。限时两个小时,每个子部分提交后可以再返回修改,这点还是很人性化的,不像有的笔试,子部分提交后就无法返回修改了,就不是那么的友好了。

题目大概都是力扣 [mid~hard] 的难度,下面切入正题吧!由于晚上还有一场笔试,具体的思路证明之类的以后再补了哈,先贴一下Code


第一题_四川麻将  题意

玩法是摸完牌之后选择3张花色一样的牌按某种顺序换给其他人。为了尽可能破坏对手的游戏体验,每次都会选择不连续的3张牌换出去。比如手上有 {1 4 5 6 8} 这5张条子,则可能会选择 {1 5 8} 这三张条子换出去。
把这个问题进行了简化,现在给你一个可重集合,并希望你从中选出一个尽可能大的子集使得其中没有两个数是 “连续” 的。

输入输出描述

输入

第一行一个整数n(1<=n<=100000),代表可重集大小
第二行n个空格隔开的整数(范围在1到200000之间),代表可重集

输出

输出满足条件的最大子集的大小

样例数据

输入

6

1 2 3 5 6 7

输出

4

AC_Code
#include 
using namespace std;
const int N = 1e5+10, M = 2e5+10;
int n, a[N], dp[M];

int main() {
	cin>>n;
	for(int i=1; i<=n; i++)  cin>>a[i];
	for(int i=1; i<=n; i++)	 dp[a[i]] = 1 ;
	
	for(int i=1; i

第二题_翻转最大子段和 题意

最大子段和是力扣上比较经典问题。这里对它进行了改编,允许在求解该问题之前翻转这个数组的连续一段,如翻转 (1,2,3.45.6) 的第3个到第5个元素组成的子数组得到的是 (1,2,5,4,3,6),求翻转后该数组的最大子段和最大能达到多少。

输入输出描述

输入

第一行—个正整数n,(1<=n<=100000),代表数组长度
第二行n个空格隔开的整数 (-1000<=ai< =1000),代表数组元素大小

输出

求翻转后所得数组的最大子段和

样例数据

输入

6

-1 3 -5 2 -1 3

输出

7

AC_Code
#include
using namespace std;
const int N = 1e5+10, inf = 1e9+10;
int n, a[N], p[N], s[N];

void solve() {
	p[0] = -inf;
	int sum=0;
	for(int i=1; i<=n; i++) {
		sum = max(0, sum) + a[i];
		p[i] = max(p[i-1], sum);
	}
	s[n+1]=-inf;	sum=0;
	for(int i=n; i>=1; i--) {
		sum = max(0, sum) + a[i];
		s[i] = max(s[i+1], sum);
	}
}

int main() {
	cin>>n;
	for(int i=1; i<=n; i++) cin>>a[i];
	solve();
	int ma = *max_element(p+1, p+n+1);
	for(int i=1; i

第三题_切豆腐 题意

为了切出更均匀的豆腐,想知道每一次下刀之后切出来的豆腐块中体积最大的那块有多大。

输入输出描述

第一行两个整数n,m (1<=n,m<=1000),代表最开始长宽高均为n厘米,总共切了m刀。
第二行m个小写字母,每个字母都是 x,y,z 中的一个。第i个代表刀垂直于哪个坐标轴。
第三行m个大于0且小于n的正整数。第i个代表第i刀所在平面到豆腐的右上角 (或者任选一个角并固定,无论选哪个角答案均相同) 的距离。
保证切的时候豆腐不会产生形变且不会产生位移。每次下刀都会把整块豆腐切开,不存在切到一半收刀,切出来的每块小豆腐都是边长为正整数的长方体。

样例数据

输入

2 3

x y z

1 1 1

输出

4

2

1

AC_Code
#include 
using namespace std;
const int N = 1e5+10, M = 2e5+10;
int n, m;

int main() 
{
	cin >> n >> m;
	vector op(m+1);
	for(int i=1; i<=m; i++) cin>>op[i];
	vector v(m+1);
	for(int i=1; i<=m; i++) cin>>v[i];
	
	multiset x,y,z;
	x.insert(0), x.insert(n);
	y.insert(0), y.insert(n);
	z.insert(0), z.insert(n);
	
	for(int i=1; i<=m; i++) 
    {
		if(op[i][0]=='x')  x.insert(v[i]);
		else if(op[i][0]=='y')  y.insert(v[i]);
		else if(op[i][0]=='z')  z.insert(v[i]);
	}
	
	int mx=0, my=0, mz=0, pre=0;
	for(auto it:x)  mx = max(mx,it-pre), pre=it;
		pre=0;
	for(auto it:y)  my = max(mx,it-pre), pre=it;
		pre=0;
	for(auto it:z)  mz = max(mx,it-pre), pre=it;
	
	vector ans(m+1);
	for(int i=m; i>=1; i--) 
	{
		ans[i] = mx*my*mz;
		if(op[i][0]=='x') 
		{
			auto it = x.find(v[i]);
			int suf = *(++it);
			it--;
			int pre = *(--it);
			mx = max(mx, suf-pre);
			x.erase(v[i]);
		}
		if(op[i][0]=='y') 
		{
			auto it = y.find(v[i]);
			int suf = *(++it);
			it--;
			int pre = *(--it);
			my = max(my, suf-pre);
			y.erase(v[i]);
		}
		if(op[i][0]=='z') 
		{
			auto it = z.find(v[i]);
			int suf = *(++it);
			it--;
			int pre = *(--it);
			mz = max(mz, suf-pre);
			z.erase(v[i]);
		}
	}
	
	for(int i=1; i<=m; i++) 
		cout << ans[i] << endl;
	return 0;
}

第四题_区间 *** 作求和 题意

给出一个长度为n的数组,进行m次数组上的区间 *** 作, *** 作包含将区间内所有数加上一个值和查询一个区间内所有数的和。如果允许重新排列初始数组中的元素并依次进行 *** 作,则 *** 作中所有查询区间和的答案之和能够达到多大?

输入输出描述

输入 

第一行有两个数 n,m(1<=n=<5000,1<=m<=500),代表数组长度和操作次数。第二行有n个数,代表初始数组中的元素,接下来m行每行 1 l r 或 2 l r k,分别代表查询下标属于 [l,r] 的元素之和这一揭作和将下标属于 [l,r] 的元素全部加上定值k。l r k 满足1<=l<=r<=n,1<=k<=5000

输出

输出若允许重新排列初始数组,进行m次 *** 作后产生的所有输出之和最大值

样例数据

输入

5 5

3 4 2 1 5

1 1 3

2 3 4 2

1 2 4

2 2 3 2

1 3 5

输出

42

AC_Code
#include 
using namespace std;
const int N = 1e5+10, M = 2e5+10;
int n, m;

int main() {
	cin>>n>>m;
	vector a(n+1);
	for(int i=1; i<=n; i++) cin>>a[i];
	ll ans_sum=0;
	vector cnt(n+1),add(n+1);
	
	for(int i=1; i<=m; i++) {
		int op; cin>>op;
		if(op==1) {
			int l,r;
			cin>>l>>r;
			for(int i=l; i<=r; i++) cnt[i]++, ans_sum += add[i];
		}
		else{
			int l,r,k;
			cin>>l>>r>>k;
			for(int i=l; i<=r; i++) add[i] += k;
		}
	}
	
    sort(a.begin()+1,a.end());
    sort(cnt.begin()+1,cnt.end());
    
    for(int i=1; i<=n; i++) 
    	ans_sum += 1LL * cnt[i] * a[i];
	cout << ans_sum << endl;
	return 0;
}

 OVER~ 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/741837.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)