美团后端笔试题解 2023.3.11 附源码

T1 100/100

总之就是找连续段长度,答案就是连续段长度/2之和

// 100 points
#include <bits/stdc++.h>
#define int long long
#define sc(a) scanf("%lld",&a)
#define pr(a) printf("%lld",a)
using namespace std;

int n;
char s[100005];

vector<int> tmp;
int ans=0;

signed main() {
	scanf("%s",s);
	n=strlen(s);
	char c=s[0];
	int cnt=0;
	for(int i=0;i<n;++i) {
		if(s[i]==c) ++cnt;
		else {
			tmp.push_back(cnt);
			c=s[i];
			cnt=1;
		}
	}
	tmp.push_back(cnt);
	for(auto i:tmp) ans+=i/2;
	pr(ans);
	return 0;
}

T2 100/100

经典dp,状态从左和上转移过来,注意颜色不同时k的判断

我不仅要吐槽,这道题题面说起点位置的金币一定为0,但实际数据可不是这样的,如果你让dp[0][0]=val[0][0]的话就会像我最开始那样45%

// 100 points
#include <bits/stdc++.h>
#define int long long
#define sc(a) scanf("%lld",&a)
#define pr(a) printf("%lld",a)
using namespace std;

int n,m,k;
int v[505][505];
char mp[505][505];
char s[505];
int dp[505][505];

signed main() {
	sc(n),sc(m),sc(k);
	for(int i=0;i<n;++i) {
		scanf("%s",s);
		for(int j=0;j<m;++j)
			mp[i][j]=s[j];
	}
	for(int i=0;i<n;++i)
		for(int j=0;j<m;++j)
			sc(v[i][j]);
	for(int i=0;i<n;++i)
		for(int j=0;j<m;++j)
			dp[i][j]=-10000000000;
	dp[0][0]=0;
	int ans=0;
	for(int i=0;i<n;++i)
		for(int j=0;j<m;++j) {
			if(i-1>=0
				&&mp[i][j]==mp[i-1][j])
					dp[i][j]=max(dp[i][j],dp[i-1][j]+v[i][j]);
			if(i-1>=0
				&&mp[i][j]!=mp[i-1][j]
				&&dp[i-1][j]>=k)
					dp[i][j]=max(dp[i][j],dp[i-1][j]-k+v[i][j]);
			if(j-1>=0
				&&mp[i][j]==mp[i][j-1])
					dp[i][j]=max(dp[i][j],dp[i][j-1]+v[i][j]);
			if(j-1>=0
				&&mp[i][j]!=mp[i][j-1]
				&&dp[i][j-1]>=k)
					dp[i][j]=max(dp[i][j],dp[i][j-1]-k+v[i][j]);
			ans=max(ans,dp[i][j]);
		}
	pr(ans);
	return 0;
}

/*
1 3 5
BBR
0 6 10
*/

T3 100/100

一个比较经典的区间覆盖问题,首先要考虑使用差分和前缀和,其次由于数据范围过大,只能使用map来统计答案

// 100 points
#include <bits/stdc++.h>
#define int long long
#define sc(a) scanf("%lld",&a)
#define pr(a) printf("%lld",a)
using namespace std;

int n;
int a[100005];
int b[100005];

map<int,int> mp;

vector<pair<int,int>> v;

signed main() {
	sc(n);
	for(int i=0;i<n;++i) sc(a[i]);
	for(int i=0;i<n;++i) sc(b[i]);
	for(int i=0;i<n;++i) {
		mp[a[i]]++;
		mp[b[i]+1]--;
	}
	int sum=0;
	for(auto i:mp) {
		sum+=i.second;
		mp[i.first]=sum;
	}
	//for(auto i:mp) cout<<i.first<<' '<<i.second<<endl;
	int mx=-1;
	for(auto i:mp) mx=max(mx,i.second);
	pr(mx);printf(" ");
	int ans=0;
	for(auto i:mp) v.push_back(i);
	for(int i=0;i<v.size();++i) {
		if(v[i].second!=mx) continue;
		if(i==v.size()-1) ++ans;
		else ans+=v[i+1].first-v[i].first;
	}
	pr(ans);
	return 0;
}
/*
3
2 1 5
6 3 7
*/

T4 81/100

可能是最折磨人的大模拟,写了一百多行,写到最后也没调出来,遂直接放弃

// 81 points
#include <bits/stdc++.h>
#define int long long
#define sc(a) scanf("%lld",&a)
#define pr(a) printf("%lld",a)
using namespace std;

char a[300],b[300];

int dpos[2]={0,0};
int wpos[2]={15,15};

int mp[16][16];

int ddir=2;
int wdir=4;

bool dfire() {
	if(ddir==1) {
		for(int i=dpos[0];i>=0;--i)
			if(i==wpos[0]&&dpos[1]==wpos[1])
				return true;
	} else if(ddir==2) {
		for(int j=dpos[1];j<16;++j)
			if(dpos[0]==wpos[0]&&j==wpos[1])
				return true;
	} else if(ddir==3) {
		for(int i=dpos[0];i<16;++i)
			if(i==wpos[0]&&dpos[1]==wpos[1])
				return true;
	} else if(ddir==4) {
		for(int j=dpos[1];j>=0;--j)
			if(dpos[0]==wpos[0]&&j==wpos[1])
				return true;
	}
	return false;
}

bool wfire() {
	if(wdir==1) {
		for(int i=wpos[0];i>=0;--i)
			if(i==dpos[0]&&wpos[1]==dpos[1])
				return true;
	} else if(wdir==2) {
		for(int j=wpos[1];j<16;++j)
			if(wpos[0]==dpos[0]&&j==dpos[1])
				return true;
	} else if(wdir==3) {
		for(int i=wpos[0];i<16;++i)
			if(i==dpos[0]&&wpos[1]==dpos[1])
				return true;
	} else if(wdir==4) {
		for(int j=wpos[1];j>=0;--j)
			if(wpos[0]==dpos[0]&&j==dpos[1])
				return true;
	}
	return false;
}

signed main() {
	scanf("%s",a);
	scanf("%s",b);
	mp[0][0]=1; // d
	mp[15][15]=2; // w
	int n=strlen(a);
	for(int i=0;i<n;++i) {
		if(a[i]=='F'&&b[i]=='F') {
			if(dfire()&&wfire()) {
				pr(i+1);
				puts("");
				printf("P");
				return 0;
			} else if(dfire()&&!wfire()) {
				pr(i+1);
				puts("");
				printf("D");
				return 0;
			} else if(!dfire()&&wfire()) {
				pr(i+1);
				puts("");
				printf("W");
				return 0;
			}
		} else if(a[i]=='F'&&b[i]!='F') {
			if(dfire()) {
				pr(i+1);
				puts("");
				printf("D");
				return 0;
			}
		} else if(a[i]!='F'&&b[i]=='F') {
			if(wfire()) {
				pr(i+1);
				puts("");
				printf("W");
				return 0;
			}
		}
		// d move
		if(a[i]=='U') {
			ddir=1;
			if(dpos[0]-1>=0&&mp[dpos[0]-1][dpos[1]]!=2)
				dpos[0]--;
		} else if(a[i]=='D') {
			ddir=3;
			if(dpos[0]+1<16&&mp[dpos[0]+1][dpos[1]]!=2)
				dpos[0]++;
		} else if(a[i]=='L') {
			ddir=4;
			if(dpos[1]-1>=0&&mp[dpos[0]][dpos[1]-1]!=2)
				dpos[1]--;
		} else if(a[i]=='R') {
			ddir=2;
			if(dpos[1]+1<16&&mp[dpos[0]][dpos[1]+1]!=2)
				dpos[1]++;
		}
		// wmove
		if(b[i]=='U') {
			wdir=1;
			if(wpos[0]-1>=0&&mp[wpos[0]-1][wpos[1]]!=1)
				wpos[0]--;
		} else if(b[i]=='D') {
			wdir=3;
			if(wpos[0]+1<16&&mp[wpos[0]+1][wpos[1]]!=1)
				wpos[0]++;
		} else if(b[i]=='L') {
			wdir=4;
			if(wpos[1]-1>=0&&mp[wpos[0]][wpos[1]-1]!=1)
				wpos[1]--;
		} else if(b[i]=='R') {
			wdir=2;
			if(wpos[1]+1<16&&mp[wpos[0]][wpos[1]+1]!=1)
				wpos[1]++;
		}
		// crush
		//if(dpos[0]==wpos[0]&&dpos[1]==wpos[1]) {
		//	pr(i);
		//	puts("");
		//	printf("P");
		//	return 0;
		//}
		mp[dpos[0]][dpos[1]]=1;
		mp[wpos[0]][wpos[1]]=2;
	}
	// count
	int wc=0,dc=0;
	for(int i=0;i<16;++i)
		for(int j=0;j<16;++j)
			if(mp[i][j]=='1') ++dc;
			else if(mp[i][j]=='2') ++wc;
	puts("256");
	if(wc>dc) printf("W");
	else if(wc==dc) printf("P");
	else printf("D");
	return 0;
}
/*
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
*/

T5 100/100

简单统计一下子树即可,非常简单

// 100 points
#include <bits/stdc++.h>
#define int long long
#define sc(a) scanf("%lld",&a)
#define pr(a) printf("%lld",a)
using namespace std;

int n,ans=0;
char v[10005];
vector<int> eg[10005];

pair<int,int> dfs(int x) {
	pair<int,int> p={0,0};
	for(auto i:eg[x]) {
		auto t=dfs(i);
		p.first+=t.first;
		p.second+=t.second;
	}
	if(p.first==p.second) ++ans;
	if(v[x-1]=='R') ++p.first;
	else ++p.second;
	return p;
}

signed main() {
	sc(n);
	scanf("%s",v);
	for(int i=2;i<=n;++i) {
		int f;
		sc(f);
		eg[f].push_back(i);
	}
	dfs(1);
	pr(ans);
	return 0;
}

#笔试##笔试复盘##美团笔试#
全部评论
靠第二题45路过
8 回复 分享
发布于 2023-03-11 21:28 广东
靠靠靠md我第二题卡45卡了半天
6 回复 分享
发布于 2023-03-11 22:37 北京
老哥很强,感谢代码,学到了,最后吐槽一下硬件方向居然和后端的题一样。。。
3 回复 分享
发布于 2023-03-11 21:27 江苏
膜拜大佬( ఠൠఠ )ノ
2 回复 分享
发布于 2023-03-11 21:30 重庆
大佬太强了
2 回复 分享
发布于 2023-03-11 21:41 重庆
还是没明白为啥第2题只过了百分之45,有xd能帮忙解释一下吗
1 回复 分享
发布于 2023-03-11 21:41 黑龙江
我21.交卷,大佬21.提交题解
1 回复 分享
发布于 2023-03-11 22:38 北京
膜拜大佬
1 回复 分享
发布于 2023-03-11 22:42 湖北
function se(s){ let i =0; let cnt = 0; while(i
1 回复 分享
发布于 2023-03-11 22:47 湖南
老哥猛啊
点赞 回复 分享
发布于 2023-03-11 21:22 广东
好牛啊
点赞 回复 分享
发布于 2023-03-11 21:31 湖南
老哥第五题是二叉树还是 树啊
点赞 回复 分享
发布于 2023-03-11 21:40 江苏
哥帮我看看我第五题错哪了,在我动态里
点赞 回复 分享
发布于 2023-03-11 21:41 安徽
感谢老哥
点赞 回复 分享
发布于 2023-03-11 21:42 河南
点赞 回复 分享
发布于 2023-03-11 21:43 陕西
你大模拟是不是没注意到每次都是找发射再自动?
点赞 回复 分享
发布于 2023-03-11 21:43 安徽
第三题线段树可以做吗?
点赞 回复 分享
发布于 2023-03-11 21:45 辽宁
膜拜大佬
点赞 回复 分享
发布于 2023-03-11 22:19 江苏
T3为什么要判断i == v.size() -1
点赞 回复 分享
发布于 2023-03-11 22:33 陕西
我服了,我说为什么第二个45%
点赞 回复 分享
发布于 2023-03-12 09:24 北京

相关推荐

预计下个星期就能开奖吧,哪位老哥来给个准信
华孝子爱信等:对接人上周说的是这周
投递华为等公司10个岗位 >
点赞 评论 收藏
分享
冲芭芭拉鸭:你这图还挺新,偷了。
投递美团等公司10个岗位
点赞 评论 收藏
分享
51 204 评论
分享
牛客网
牛客企业服务