美团2020后天开发岗笔试题

一共五道题,四道基础题,一道压轴题,每题各20分,一共100分,时间为120分钟。

第一题:

题目场景为计算所有顾客对一家店铺的‘星级’计算。
input:
第一行输入一个数 五个数,每个数中间用空格隔开(例如: 4 5 6 7 8 9)(1 ≤ x ≤ 20000)
output:
输出五个数的加权平均,权值依次为[1 ,2 ,3 ,4 ,5],结果保留一位小数(例如5.784,要保留5.7,不要产生进位)

样例:
200 400 500 600 800
3.5
代码实现:

#include <iostream>
#include <math.h>
using namespace std;
int main(){
    int N = 5;
    int arr[5];
    for(int i =0;i < N;i++)
        cin>>arr[i];
    int sum =0;
    int counter =0;
    for(int i =0;i < N;i++)
    {
        sum += arr[i]*(i+1);
        counter += arr[i];

    }
    //对于不进位的计算,采用了floor函数,现将结果扩大10倍   
    float res = floor(1.0*sum/counter * 10)/10;
    cout<<res<<endl;
    return 0;    
}

测试结果:通过显示%73的用例

第二题:

优惠券使用问题,美团退出满x优惠y的活动,x不一定大于y,例如x =1 ,y =2,这种情况下,店家直接按照两元优惠商品,但是不会找钱给顾客,问题小明有若干优惠券,计算小明在尽可能多使用优惠券的情况下,购买商品的总的价格和实际支付的金额数。
input:
第一行输入一个N,表示小明拥有的优惠卷数;
接下面N行,每行输入两个数x、y,表示该优惠卷满x可以优惠y元。
output:
一行,输出两个数,第一个数为商品总的价格,第二个数为实际支付的金额数。

样例:
input:
4
2 8
4 9
1 2
6 10
output:
29 15
代码实现:


#include <iostream>
#define M 50000

using namespace std;

int main(){
    int N ;
    cin>>N;
    int arr[M][2];
    for(int i =0;i < N;i++)
    {
        cin>>arr[i][0];
        cin>>arr[i][1];
    }
    int total =0,discount = 0;
    for(int i =0;i < N;i++)
    {
//        cout<<arr[i][0]<<", "<<arr[i][1]<<endl;
        total += max(arr[i][0],arr[i][1]);//选择x,y最大的作为实际购买商品的价格
        discount += arr[i][1];
    }
    cout<<total<<" "<<total - discount<<endl;

    return 0;

}

测试结果:
AC

第三题:

路径规划问题,一个花店有很多订单用户,外卖小哥要从花店给顾客送花,外卖小哥可以一次取多束华花,问题求花店到所有顾客的所有路径和也即,图片说明
始终用数字1,表示花店,ui表示顾客位置(1,ui)表示花店到顾客的距离,同时也便是这两点存在一条路,和外卖小哥实际走的最短路径,外卖小哥每次的最短路径中不用每次送完花然后再返回花店,假设n个地方只有n-1路径,也即到一个地点只有提条路。
input:
第一行输入一个N,表示花店和顾客的总数(这点算是一个小小的陷阱吧);接下来(N-1)行每行表示三个数,x、y、z分别表示地点i,地点j,z表示两个地点之间的距离。
output:
输出一行两个数,第一个数表示花店到所有顾客的所有路径,第二个数是外卖小哥实际走的最短路径。

样例:
input:
5
1 2 3
1 3 2
1 4 1
2 5 1
output:
10 10
结果分析:外卖小哥走的路线可以为:1-3-1-4-1-3-5,所以结果是10,应为1-3-5这条路径最长,所有一定要最后一定最后走,因为不用返回1了,其他需要返回,不是表示返回花店买花,二是表示要到其他店铺,必须通过1才能到达。
代码:

#include <iostream>
#define M 300
using namespace std;
int find2(int i,int arrdis[2][M],int markers[])
{
    int res = 0; 
    while(arrdis[0][i]!=0)//arrdis[i] == 0表示访问到花店
    {
        res += arrdis[1][i];
        if(markers[i]==0)//第一次访问 
        {
            markers[i] = 1; 
        }
        else if(markers[i]==1)//已经访问过
        {
            markers[i] = 2; //再次访问就删除,因为总是从后往前访问 
        } 
//        cout<<i<<" ";
        i =  arrdis[0][i];//继续向前访问 
    } 
//    cout<<endl; 
    return res;
}
int main(){
    int N ;
    cin>>N;
    int arr[M][3];
    for(int i =0;i < N-1;i++)
    {
        cin>>arr[i][0];
        cin>>arr[i][1];
        cin>>arr[i][2];
    }
    //dis,realdis分别表示花店到所有点的路径已经外卖小哥实际做的而路径
    int dis = 0,readis = 0; 
    int arrdis[2][M]={0};//存储位置之间的关系和距离 
    for(int i =0;i < N;i++)
    {
        arrdis[0][ arr[i][1] ] = arr[i][0];
        arrdis[1][ arr[i][1] ] = arr[i][2];
    } 
    //求各个顾客到花店的路径和路径长度 
    int markers[M] ={0}; //0表示未访问,1表示保留,2表示重复删除 
    int path[M] = {0};//花店到各个顾客的距离 
    for(int i =2;i <= N;i++)
    {
        path[i] = find2(i,arrdis,markers);//顾客i到花店的路径长度

     } 
     //将重复的路径删除,只保留花店到顾客中不重复的路径
     // 计算外卖小哥的实际所有最短路径长度
    int realdis = 0;
    int maxValue = 0;//记录最长的路径 
    for(int i =2;i <= N;i++)
    {
        //cout<<markers[i]<<","<<path[i]<<endl;
        dis += path[i];
        if(markers[i]==1)
        {
            //每条路径都计算二倍 ,
            //最后减去一倍路径作为外卖小哥的实际走的路程 
            realdis += path[i]*2;
            if(path[i] > maxValue)
                maxValue = path[i];
        }
     }   

    cout<<dis<<" "<<realdis-maxValue<<endl; 
    return 0;

}

测试结果:
当时没有通过,后来补充的。

第四题:

场景
input:
output:
样例:
代码:
测试结果:

第四题:
场景
小明有一堆不面额的代金券,顺序打乱,例如2,1,1,2,1,如果相邻两个代金券相同,可以进行一次合并,2,2,2,1,合并一次可以得到一张无限期使用的1元券,求小明最多可以得到多少无限期的1元卷。
input:
第一行输入N(2≤N≤500),表示代金券的个数,第二行输入N个数,分别表示代金券的面额x(1xi≤1000)。
output:
输出一个整数,表示获得的代金券的个数。
样例:
input:
5
2 1 1 2 1
output:
2
结果解释:2 2 2 1,4 2 1,无法合并合并两次

Method1:暴力破解
最多有500张代金券,每张最大100,合并后最大的结果不超过50,000;写一个两层for循环,主轮对不同面试的代金券进行合并,每一轮只合并一代金券
代码:

#include <iostream>
#define M 500
using namespace std;

int main(){
    int N ;
    cin>>N;
    int arr[M]; 
    for(int i =0;i < N;i++)
    {
        cin>>arr[i];
    }
    int amount = N;//当前代金券的数量
    int flag = true;//是否有可以合并的代金券 
    int t = 0;//奖励数 
    int temp[500];//存储合并后的结果 
    int res = 0;
    for(int j =1;j < 50000&&amount > 1;j++ )
    { 
//         flag = true;
//        amount = t;
        t = 0;
        for(int i  =0;i < amount-1; )
        {
             if(arr[i]==arr[i+1] &&arr[i]==j)
             {
                 res++;
                 temp[t++] = arr[i]+arr[i+1];
                 i+=2;
//                 flag = true
             }
             else
             {
                 temp[t++] = arr[i];
                 i++;
             }
        }
        for(int i =0;i < t;i++)
        {
            arr[i] = temp[i];
        }
        amount = t;
    }


    cout<<res<<endl;
    return 0;

}

测试结果:通过%43的用例

最后一题是关于红黑树测算法,属于专业测试题。

全部评论

相关推荐

11-27 12:43
已编辑
门头沟学院 C++
点赞 评论 收藏
分享
牛客279957775号:铁暗恋
点赞 评论 收藏
分享
沉淀一会:**圣经 1.同学你面试评价不错,概率很大,请耐心等待;2.你的排名比较靠前,不要担心,耐心等待;3.问题不大,正在审批,不要着急签其他公司,等等我们!4.预计9月中下旬,安心过节;5.下周会有结果,请耐心等待下;6.可能国庆节前后,一有结果我马上通知你;7.预计10月中旬,再坚持一下;8.正在走流程,就这两天了;9.同学,结果我也不知道,你如果查到了也告诉我一声;10.同学你出线不明朗,建议签其他公司保底!11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
蚂蚁 基架java (n+6)*16 签字费若干
点赞 评论 收藏
分享
评论
2
4
分享
牛客网
牛客企业服务