美团9月6日后台开发 笔试 编程题

第一题
给定一张包含N个点、N-1条边的无向连通图,节点从1到N编号,每条边的长度均为1。假设你从1号节点出发并打算遍历所有节点,那么总路程至少是多少?
输入
第一行包含一个整数N,1≤N≤100000。
接下来N-1行,每行包含两个整数X和Y,表示X号节点和Y号节点之间有一条边,1≤X,Y≤N。
输出
输出总路程的最小值。
思路:走完所有节点类似于深度优先搜索,也就是说除了最后一条路径外,别的路径都经历了正着走,再返回
的过程,也就是两遍,设最后一条路径为x,总分支数为n-1,总路径=2*(n-1-x)+x=2*n-2-x,当x最大时
总路径最小,所以转化为求多叉树的深度。
#include<bits/stdc++.h>
using namespace std;
int lst[100005];
int main(){
int n;
while(cin>>n){
memset(lst,0,sizeof(lst));
for(int i = 0;i<n-1;i++){
int a,b;
cin>>a>>b;
lst[b] = lst[a]+1;//当前节点的深度
}
int depth = 0;
for(int i = 1;i<=n;i++)
depth = lst[i]>depth?lst[i]:depth;//找到最大值
cout<<2*n-2-depth<<endl;
}
return 0;
}

第二题
小明拿到了一个数列a1 , a2 , ... an ,小明想知道存在多少个区间[l,r]同时满足下列两个条件:
1、r-l+1=k;
2、在a l , a l+1,...ar中,存在一个数至少出现了 t 次。
输出满足条件的区间个数。
思路:
先判断n和k的关系,若k>n,直接返回0,若k<n,再进行后续计算
设置一维数组lst[10005],保存数列中值出现次数
设置count,保存ar-al中出现t次及以上数的个数
设置num,保存区间数
首先从0到n-k-1遍历一遍,对lst、count、num进行初始化
然后将窗口向右滑动,每次从头去一个,从尾部添加一个,动态维护lst、count、num的值
最后输出num的值即可
#include<bits/stdc++.h>
using namespace std;
int lst[10005];
int main(){
int n,k,t;
while(cin>>n>>k>>t){
if(k<=n){
vector<int> vec;
memset(lst,0,sizeof(lst));
for(int i = 0;i<n;i++){
int x;
cin>>x;
vec.push_back(x);
}
int count = 0;
int num = 0;
for(int i = 0;i<k;i++){
lst[vec[i]]++;
if(lst[vec[i]]==t)
count++;
}
if(count>0)
num++;
for(int i = 0;i<n-k;i++){
lst[vec[i]]--;
if(lst[vec[i]]==t-1)
count--;
lst[vec[i+k]]++;
if(lst[vec[i+k]]==t)
count++;
if(count>0)
num++;
}
cout<<num<<endl;
}
else
cout<<0<<endl;
}
return 0;
}


#美团##笔试题目##题解#
全部评论
神仙
点赞
送花
回复
分享
发布于 2018-09-06 21:16
#include <iostream> #include <unordered_map> using namespace std; class Solution { public: int findNumOfSection(vector<int> arr, int k ,int t){ int ret = 0; unordered_map<int, int> record;//val:frequency //滑动窗口为[i,j] j=k+i-1; for (int i = 0 ; (k+i-1) < arr.size(); i++) { for (int j =i; j<= k+i-1; j++) { record[arr[j]]++; } for (unordered_map<int, int>::iterator iter = record.begin(); iter != record.end(); iter++){ if (iter->second >= t){ ret++; break; }else continue; } record.clear(); } return ret; } }; int main(int argc, char const *argv[]) { int n,k,t; if ( n<k || t<=0) { return 0; } while (cin>>n>>k>>t) { std::vector<int> vec; for (int i = 0; i < n; i++) { int temp; cin>>temp; vec.push_back(temp); } cout<<Solution().findNumOfSection(vec,k,t)<<endl; } return 0; }
点赞
送花
回复
分享
发布于 2018-09-06 22:23
网易互娱
校招火热招聘中
官网直投
我等渣渣选择先把图存起来再DFS查深度 #include <iostream> using namespace std; int a[10005][10005]={0}; int b[10005]={0}; int len=0; int n=0; int deep=0; int func(int k) {     for(int i=0;i<10005;i++)     {         if(a[k][i]==1 && b[i]==0){             b[i]=1;             len++;             func(i);             if(len>deep)                 deep=len;             len--;         }     }     return 0; } int main() {     int start,end;     cin>>n;     for(int i=0;i<n-1;i++)     {         cin>>start>>end;         a[start][end]=1;     }     b[1]=1;     func(1);     cout<<(n-1)*2-deep; }
点赞
送花
回复
分享
发布于 2018-09-06 23:19
这么早就把代码放出来,回头被别人抄走,你们都会被判作弊的吧.......
点赞
送花
回复
分享
发布于 2018-09-06 21:19
怕了怕了
点赞
送花
回复
分享
发布于 2018-09-06 21:20
美团还是凉
点赞
送花
回复
分享
发布于 2018-09-06 21:20
楼主第一题AC了吗
点赞
送花
回复
分享
发布于 2018-09-06 21:24
大佬
点赞
送花
回复
分享
发布于 2018-09-06 21:25
大佬算法咋练啊,也一直在刷题,还是不会做
点赞
送花
回复
分享
发布于 2018-09-06 21:26
校友,校友。。。牛皮
点赞
送花
回复
分享
发布于 2018-09-06 21:29
问一下,第一题算深度那块,如果较深的点先出现,深度不就算错了吗
点赞
送花
回复
分享
发布于 2018-09-06 21:44
大佬,第一题真的AC了吗?我记得应该是求的遍历这个图的所有路径和啊,你求这个二叉树的深度,应该只算了一条路径吧。
点赞
送花
回复
分享
发布于 2018-09-06 21:44
只有2个题目吗
点赞
送花
回复
分享
发布于 2018-09-06 21:50
第一题没说是二叉树
点赞
送花
回复
分享
发布于 2018-09-06 21:51
妈的,第一题原来这么骚,大佬牛皮。。。 Orz  是我配不上,太蠢了
点赞
送花
回复
分享
发布于 2018-09-06 21:54
第一题,输入的x是默认大于y的吗,会不会有影响?
点赞
送花
回复
分享
发布于 2018-09-06 21:56
nb
点赞
送花
回复
分享
发布于 2018-09-06 21:59
第一题相对简单,想到了方法就可以ac;第二题我被搞懵了,我感觉思路正确,可是就是卡在了36%
点赞
送花
回复
分享
发布于 2018-09-06 22:13
lst[b] = lst[a]+1;//当前节点的深度 这个是一定的么? 万一先给后面层的边
点赞
送花
回复
分享
发布于 2018-09-06 22:25
有可能除了1的点有分支吧,遍历这个分支下的点就不用回到1了啊,所以比如1-2 1-3 2-4 2-5 5-6,遍历了4再去遍历5,只需回退到点2就行了,不用回1
点赞
送花
回复
分享
发布于 2018-09-07 11:10

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务