美团笔试编程题

美团笔试编程题练习

第一题


import java.io.IOException;

import java.util.Arrays;

import java.util.Scanner;


/**
 * @author zwghdu
 * @create 2021-08-25-8:35
 */
/*
小团的蛋糕铺长期霸占着美团APP中“蛋糕奶茶”栏目的首位,因此总会吸引各路食客前来探店。
小团一天最多可以烤n个蛋糕,每个蛋糕有一个正整数的重量。
早上,糕点铺已经做好了m个蛋糕。
现在,有一个顾客要来买两个蛋糕,他希望买这一天糕点铺烤好的最重的和最轻的蛋糕,并且希望这两个蛋糕的重量恰好为a和b。
剩余的n-m个蛋糕可以现烤,请问小团能否满足他的要求?


输入包含多组数据,每组数据两行。
每组数据的第一行包含4个整数,n,m,a,b,空格隔开。这里不保证a和b的大小关系。
接下来一行m个数,空格隔开,代表烤好的蛋糕重量
*/
/*

模拟一下,在保证a<b的情况下,有如下几种情况:
(1) 已经烤好的蛋糕中,重量最小的比a轻,或者重量最大的比b重,肯定无法满足要求。
(2) 已经烤好的蛋糕重量都在区间[a,b]中
    i) 已经有a和b两个重量,可以满足要求。
    ii) 已经有a或b之中的一个重量,并且还能现烤的蛋糕数不少于1,那就肯定还能够烤一个需要的重量;否则不能满足要求。
    iii) 需要的两个重量都没有,并且能还能现烤的蛋糕数不少于2,那就肯定可以把需要的两个重量都烤了;否则不能满足要求。

*/
public class Main {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        String[] str;
        while(sc.hasNextLine()){
            str= sc.nextLine().trim().split(" ");
            int n = Integer.parseInt(str[0]);
            int m = Integer.parseInt(str[1]);
            int a = Integer.parseInt(str[2]);
            int b = Integer.parseInt(str[3]);
            str= sc.nextLine().trim().split(" ");
            int[] weight = new int[m];
            for (int i = 0; i < m; i++) {
                weight[i] = Integer.parseInt(str[i]);
            }
            Arrays.sort(weight);
            if(a>b){
                int t = b;
                b = a;
                a = t;
            }
            if(a>weight[0] || b<weight[m-1]){
                System.out.println("NO");
            }else if(a==weight[0] && b==weight[m-1]){
                System.out.println("YES");
            }else if(a==weight[0] && n-m>=1){
                System.out.println("YES");
            }else if(b==weight[m-1] && n-m>=1){
                System.out.println("YES");
            }else if(n-m>=2){
                System.out.println("YES");
            }else{
                System.out.println("NO");
            }
        }
        sc.close();
    }
}


第二题

import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;

/**
 * @author zwghdu
 * @create 2021-08-25-9:49
 */
/*
    小团是某综艺节目的策划,他为某个游戏环节设计了一种晋级规则,已知在这个游戏环节中每个人最后都会得到一个分数score_i,
    显而易见的是,游戏很有可能出现同分的情况,小团计划该环节晋级人数为x人,则将所有人的分数从高到低排序,
    所有分数大于等于第x个人的分数且得分不为0的人都可以晋级。
    请你求出本环节的实际晋级人数。显然这个数字可能是0,如果所有人的得分都是0,则没有人满足晋级条件。

    输入第一行包含两个正整数n和x,分别表示参加本环节的人数,和小团指定的x。
    输入第二行包含n个整数,每个整数表示一位选手的得分。

    输出仅包含一个整数,表示实际晋级人数。
 */

public class Main {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        String[] str;
        while(sc.hasNextLine()){
            str = sc.nextLine().trim().split(" ");
            int n = Integer.parseInt(str[0]);
            int x = Integer.parseInt(str[1]);
            str = sc.nextLine().trim().split(" ");
            int[] score = new int[n];
            for (int i = 0; i < n; ++i) {
                score[i] = Integer.parseInt(str[i]);
            }
            Arrays.sort(score);
            if(x==0){
                System.out.println(0);
                break;
            }
            if(score[n-1]==0){
                System.out.println(0);
                break;
            }
            if(score[0]==score[n-1]){
                System.out.println(n);
                break;
            }
            if(score[n-x]==0){
                for (int i = n-x; i < n; ++i) {
                    if(score[i] !=0){
                        System.out.println(n-i);
                        break;
                    }
                }
            }else{
                int count=0;
                for(int i=0;i<n-x;++i){
                    if(score[i]==score[n-x]){
                        count+=1;
                    }
                }
                System.out.println(count+x);
            }
        }
        sc.close();
    }
}

第三题

/**
 * @author zwghdu
 * @create 2021-08-25-10:43
 */
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
/*
小美请小团吃回转寿司。转盘上有N盘寿司围成一圈,第1盘与第2盘相邻,第2盘与第3盘相邻,…,第N-1盘与第N盘相邻,第N盘与第1盘相邻。
小团认为第i盘寿司的美味值为A[i](可能是负值,如果小团讨厌这盘寿司)。
现在,小团要在转盘上选出连续的若干盘寿司,使得这些寿司的美味值之和最大(允许不选任何寿司,此时美味值总和为0)。

第一行输入一个整数T(1<=T<=10),表示数据组数。
每组数据占两行,第一行输入一个整数N(1<=N<=10^5);
第二行输入N个由空格隔开的整数,表示A[1]到A[N](-10^4<=A[i]<=10^4)。

每组数据输出占一行,输出一个整数,表示连续若干盘寿司的美味值之和的最大值。
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine().trim());
        while(T-- > 0){
            int n = Integer.parseInt(br.readLine().trim());//盘子的数目
            String[] strArr = br.readLine().trim().split(" ");//美味值
            int[] yummy = new int[n];
            int sum = 0;//保存美味值之和
            for(int i = 0; i < n; i++){
                yummy[i] = Integer.parseInt(strArr[i]);
                sum += yummy[i];
            }
            // 为了降低时间复杂度,可以两种情况一起求
            int max = yummy[0];
            int min = yummy[0];
            int dpMax = yummy[0];
            int dpMin = yummy[0];
            for(int i = 1; i < n; i++){
                dpMax = Math.max(dpMax + yummy[i], yummy[i]);
                max = Math.max(max, dpMax);
                dpMin = Math.min(dpMin + yummy[i], yummy[i]);
                min = Math.min(min, dpMin);
            }
            System.out.println(Math.max(sum - min, max));
        }
    }
}

第四题

import java.util.*;

/**
 * @author zwghdu
 * @create 2021-08-25-16:24
 */
/*


小团找到一颗有n个节点的苹果树,以1号节点为根,且每个节点都有一个苹果,苹果都有一个颜色,但是这棵树被施加了咒术,
这使得小团只能从某一个节点的子树中选取某一种颜色的拿。小团想要拿到数量最多的那种颜色的所有苹果,请帮帮她。
每次她会指定一个节点t,如果小团只能从节点t的子树中选取某一种颜色的苹果,选取什么颜色能拿到最多的苹果?
如果有多种颜色都可以拿同样多的苹果,输出颜色编号最小的那个对应的编号。

节点x的子树定义为所有将x当作祖先的节点,x也视为x的子树的一部分。

第一行一个正整数n表示这颗树上节点的个数。
接下来n-1行,每行两个正整数x­­i,yi,表示树上第i条边连接的两个节点。
接下来一行n个正整数c­i,分别表示从1~n号节点上的苹果的颜色。
接下来一行一个正整数q,表示接下来有q次独立的询问。
接下来q行,每行一个正整数t表示询问:如果小团只能从节点t的子树中选取某一种颜色的苹果,选取什么颜色能拿到最多的苹果?
如果有多种颜色都可以拿同样多的苹果,输出颜色编号最小的那个对应的编号。
对于100%的数据n≤5000, 1≤xi,yi,t≤n, ci≤1000000000,q≤1000

输出q行,每行一个整数,表示答案。
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //读取树节点的个数
        int treeSize = sc.nextInt();
        //构建无向图
        Map<Integer, List<Integer>> graph = new HashMap<>();
        for (int i = 0; i < treeSize-1; ++i) {
            int father = sc.nextInt();
            int son = sc.nextInt();
            List<Integer> fatherList = graph.getOrDefault(father,new ArrayList<>());//存储相关联的节点
            List<Integer> sonList = graph.getOrDefault(son,new ArrayList<>());//存储相关联的节点
            fatherList.add(son);
            sonList.add(father);
            graph.put(father,fatherList);//构建边
            graph.put(son,sonList);
        }
        //调整无向图为有向图
        modify(1,graph);
        //读取每个节点的颜色
        Map<Integer,Integer> dictionary = new HashMap<>();
        for (int i = 0; i < treeSize; ++i) {
            int color = sc.nextInt();
            dictionary.put(i+1,color);
        }
        //读取询问的次数
        int times = sc.nextInt();
        Map<Integer,Integer> counter = new TreeMap<>();//计数器;TreeMap存储是有序的;存储对从开始询问节点到结束,相同颜色的数量
        for (int i = 0; i < times; i++) {
            //读取开始询问节点
            int root = sc.nextInt();
            //深度搜索从询问节点开始的各个颜色的数量
            dfs(root,dictionary,graph,counter);
            //把counter中的值存储到list集合中进行排序
            List<Integer> count = new ArrayList<>(counter.values());
            Collections.sort(count);
            //获取最大值所对应的颜色
            for (Map.Entry<Integer, Integer> entry : counter.entrySet()) {
                if(entry.getValue() == count.get(count.size()-1)){
                    System.out.println(entry.getKey());//输出能拿到最多苹果的颜色
                    break;
                }
            }
            counter.clear();
        }

    }

    private static void dfs(int root, Map<Integer, Integer> dictionary, Map<Integer, List<Integer>> graph, Map<Integer, Integer> counter) {
        int color = dictionary.get(root);
        counter.put(color,counter.getOrDefault(color,0)+1);
        for(int son : graph.get(root)){
            dfs(son,dictionary,graph,counter);
        }
    }

    private static void modify(Integer root, Map<Integer, List<Integer>> graph) {
        List<Integer> fatherList =  graph.get(root);//获取与root节点相关联的值
        if(fatherList.size() == 0){
            return;
        }
        for (Integer son : fatherList) {
            List<Integer> sonList = graph.get(son);
            sonList.remove(root);//删除儿子节点中与父亲节点相关联的值
            graph.put(son,sonList);//把删除后的结果重新放入
            modify(son,graph);//递归删除
        }
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Listen·Rain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值