4.30美团笔试题解

题目来源https://www.nowcoder.com/discuss/945361?type=post&order=create&pos=&page=0&ncTraceId=&channel=-1&source_id=search_post_nctrack&gio_id=6425811C756AF923268430F6BE3431C9-165****828384

第一题:小美的01串

小美有两个01串s,t。她想求s和t的所有长度等于|s|子串(连续)的汉明距离的和。即,她想知道: 汉明距离(ti, s) ,其中ti指第i个字符开始的长度为|s|的子串。
对于等长01串a, b,他们之间汉明距离的定义是
输入描述:
对于每组数据,包含两行数据,第一行是s, 第二行是t;
1≤|s|≤|t|≤50000
输出描述:
输出一一个整数,表示汉明距离的和。

思路:直接暴力就能过了(听说python卡了?)
#include<bits/stdc++.h>
using namespace std;

#define int long long

signed main(){
	string s,t;
	cin>>s>>t;
	int ans=0;
	for(int i=0;i<t.length();i++){
		for(int j=0;j<s.length();j++){
			if(t[i+j]!=s[j])ans++;
		}
	}
	cout<<ans<<endl;
}



第二题: 菱形图

图是指-个无向图形成的环,满足点数大于等于4,其中可以找到四个不相同的点a,b,c,d,使得a→b, b→c, c→d, d→a的距离都相等。
小美刚刚学完图论。她随手造了一张n个点m条无向边的图(不含重边和自环,保证连通,即任意两个点都互相可达),她想知道这张图是不是菱形图。(本题目中,我们默认两点之间的距离为1)。
输入描述:
第一行一个正整数T,表示有T组数据。
对于每一组数据,第一行两个正整数n, m,表示无向图的点数和边数:
第二行m个正整数ui;第三行m个正整数vi,表示ui与vi之间有一条无向边。数据保证无重边和自环且图连通。数字间两两有空格隔开。

输出描述
其是菱形图,输出一行Yes;否则,输出一行No。

思路:判断它是否为环,为环的话是否是4的倍数,(欢迎大佬评论区补充这道题的正解)

提一下本题数据弱,用以下的代码本来想测试一下,结果直接过了全部测试用例(这个是能有数据hack的)
#include<bits/stdc++.h>
using namespace std;

#define int long long
int u[10005],v[10005],g[10005][1005];
signed main(){
	int t,n,m;
	cin>>t;
	while(t--){
		cin>>n>>m;
		for(int i=1;i<=m;i++){
			cin>>u[i];
		}
		for(int i=1;i<=m;i++){
			cin>>v[i];
		}
		if(n!=m||n%4!=0)cout<<"No"<<endl;
		else cout<<"Yes"<<endl;
	}
}


第三题:小美的仓库

美的家乡遇到了特大暴雨。为此她建立了一一个救援的大米仓库。有货车运来或取走大米。现在有列车队,每个车都要运来或取走一定的大米。 假设小美的仓库最开始有M千克大米,它会在某辆车路过时打开仓库,这样这辆车以及后面的车辆都可以进入仓库运来或取走大米。如果有一辆车取不到本想取到的大米,小美会提前关闭仓库,这辆车以及后面的车辆都不再能进入仓库。(即小美的仓库
会对车队的一个连续子串开放,且保证仓库内的大米不为负值),请问小美的仓库最多有多少辆车进入。
输入描述:
对于每一组数据, 包含两行数据,
第一行是车队的车辆数n和小美仓库本有的大米m,
第二行是车队想取走(负值)或运来(正值)的大米a,数字间两两有空格隔开。

输出描述:
仓库最多有多少辆车进入?

思路:求最长的一段符合要求的连续序列,典型的滑动窗口
(这道题考虑过能不能用滑动窗口,因为这道题是有负值的,这种情况考虑用单调队列优化,但是有m值限制,一时想不出方案,后面想了想,假设m为0,[1,-3,1,1]这段序列是为0的,使用滑动窗口判断会有问题的,但是这道题有点特殊,他要求前缀段也要符合,所以可以使用滑动窗口)
#include<bits/stdc++.h>
using namespace std;

#define int long long
int a[50005];
signed main(){
	int n,m;
	cin>>n>>m;
	int l=1,ans=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		m+=a[i];
		while(m<0){
			m-=a[l++];
		}
		ans=max(ans,i-l+1);
	}
	cout<<ans<<endl;
}

第4题:小美买饮料

美的班上要组织班级聚会啦!老师交给小美一个任务:去给聚会采购果汁饮料。
小美来到超市,发现超市里面一共有n种不同的果汁饮料,种类标记为1,2...,n。每一种饮料都有一个美味度ai, ai越大,说明饮料越好喝。但是,由于有些果汁饮料味道可能很奇怪,于是ai有可能小于等于0。
由于不知道每个同学的口味,每一种饮料小美都恰好买了一瓶。这时,小美在思考:能不能找到这样一对I,r满足1 <= l <= r <=n,且不满足[l,r]=[1,n] (即全选),使得[l.r]将这个种类内的饮料各买一瓶,其美味度之和大于等于每种饮料都买瓶的美味度之和?
输入描述:
第一行一个正整数T,表示有T组数据。
对于每组数据,第1行一个正整数n;第二行n个整数a1,02. ... ,an. 

输出描述
对于每一组数据,如果找得到这样的,输出Yes; 否则,输出No。

思路:[l,r]的序列可能是少了左边一段,或者少了右边一段,亦或者是俩边都少了,只要左边这段或者右边这段是<=0的,是不是就符合题目要求了,
所有直接遍历俩遍,判断左边是否存在<=0的段和右边是否存在<=0的段
#include<bits/stdc++.h>
using namespace std;

#define int long long
int a[50005];
signed main(){
	int t,n,k1,k2,flag;
	cin>>t;
	while(t--){
		cin>>n;
		flag=0,k1=0,k2=0;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			k1+=a[i];
			if(k1<=0){
				flag=1;
			}
		}
		for(int i=n;i>=1;i--){	
			k2+=a[i];
			if(k2<=0){
				flag=1;
				break;
			}
		}
		if(flag==1)cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
}

第5题:铺路

一段长为n的路,每次可以铺w米,事先已经进行了m次铺路的操作,随后给出m次铺路的起点p
输出描述:最少还要多少次才能将路铺好

思路:先将标记了事先铺路起点的数组排序,根据这个算出俩段铺路之间未铺的长度,算出这个长度最少需要铺几次
#include<bits/stdc++.h>
using namespace std;

#define int long long
int m,n,w;
int a[10005];
signed main() {
	cin>>m>>n>>w;
	for(int i=1; i<=m; i++) {
		cin>>a[i];
	}
	int ans=0;
	int l=0;
	sort(a+1,a+m+1);
	for(int i=1; i<=m; i++) {
		if(a[i]>l) {
			ans+=(a[i]-l)/w;
			if((a[i]-l)%w!=0)ans++;
		}
		l=a[i]+w;
		cout<<ans<<endl;
	}
	ans+=(n-l)/w;
	if((n-l)%w!=0)ans++;
	cout<<ans<<endl;
}




#美团##实习##笔经#
全部评论

相关推荐

4 13 评论
分享
牛客网
牛客企业服务