8月6日美团笔试题-后端AK代码

4 + 1 全部100%通过,但代码像shit一样,心情好时候再重构一下。

第一题,礼品盒分配

  • 解题思路:分情况进行讨论,礼盒数取决于 A B 最小值 和 A B 间的差值

    • 可以看做,先在每个礼盒中放入 一个 A 和 一个 B

    • max - min,就是在每个盒子中放入 1 A 和 1 B 后剩余的 sub

    • 如果 sub >= min,那么所有礼盒都可以满足 3 个礼品

    • 否则,不能将第一步中所有礼盒装满,直接返回 ( A + B) / 3即可

      public class Main {
      public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int T = input.nextInt();
        while (T-- > 0){
            int num1 = input.nextInt();
            int num2 = input.nextInt();
            System.out.println(getAns(num1, num2));
        }
      }
      public static int getAns(int x, int y){
        int min = Math.min(x, y), max = Math.max(x, y), sub = max - min;
        if(sub >= min) return min;
        else return (max + min) / 3;
      }
      }

      第二题 实验结果

      结题思路:

    • 采用 left 数组保存 i 之前的小于等于0的数量

    • 采用 right 数组保存 i 之后大于等于0的数量
      遍历即可

      public class Main {
      public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNextLine()){
            int n = Integer.parseInt(input.nextLine());
            String[] line = input.nextLine().split(" ");
            int[] nums = new int[n];
            for(int i = 0; i < n; ++i) nums[i] = Integer.parseInt(line[i]);
      
            int[] left = new int[n], right = new int[n];
      
            int ans = n, count = 0;
            for(int i = 0; i < n; ++i){
                if(nums[i] >= 0) ++count;
                left[i] = count;
            }
            count = 0;
            for(int i = n - 1; i >= 0; --i){
                if(nums[i] <= 0) ++count;
                right[i] = count;
            }
            for(int i = 0; i <= n; ++i){
                int l = i == 0 ? 0 : left[i - 1];
                int r = i == n ? 0 : right[i];
                ans = Math.min(ans, l + r);
            }
            System.out.println(ans);
        }
      }
      }

第三题,魔法石

  • 首先根据第二行,进行预处理,对经过反转可以得到的数字进行统计
  • 再对第一行数据,进行排序,排序的作用就是计算相同数字的最大数量
  • 当 相同数字数量 + 反转数字可以得到的数量 >= (n + 1) / 2
  • 记录最小的翻转次数 (n + 1) / 2 - count
public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNextLine()){
            int n = Integer.parseInt(input.nextLine());
            int[][] arr = new int[n][2];

            String[] line = input.nextLine().split(" ");
            for(int i = 0; i < n; ++i) {
                arr[i][0] = Integer.parseInt(line[i]);
            }
            line = input.nextLine().split(" ");
            for(int i = 0; i < n; ++i) {
                arr[i][1] = Integer.parseInt(line[i]);
            }

            Arrays.sort(arr, (o1, o2) -> o1[0] - o2[0]);
            // map 记录由 第二行反转 每个数字 及由反转得到的最大数量
            Map<Integer, Integer> map = new HashMap<>();
            for(int i = 0; i < n; ++i){
                if(arr[i][1] != arr[i][0]) map.put(arr[i][1], map.getOrDefault(arr[i][1], 0) + 1);
            }

            int count = 1, ans = -1;

            for(int i = 1; i < n; ++i){
                if(arr[i][0] == arr[i - 1][0]){
                    ++count;
                    // 当 第一行数量 + 第二行反转数量 >= (n + 1) / 2,即满足要求
                    if(i == n - 1){
                        if(count + map.getOrDefault(arr[i][0], 0) >= (n + 1) / 2){
                            if(count >= (n + 1) / 2) ans = 0;
                            else{
                                if(ans == -1) ans = (n + 1) / 2 - count;
                                else ans = Math.min(ans, (n + 1) / 2 - count);
                            }
                        }
                    }
                }else{
                    // 当 第一行数量 + 第二行反转数量 >= (n + 1) / 2,即满足要求
                    if(count + map.getOrDefault(arr[i - 1][0], 0) >= (n + 1) / 2){
                        if(count >= (n + 1) / 2) ans = 0;
                        else{
                            if(ans == -1) ans = (n + 1) / 2 - count;
                            else ans = Math.min(ans, (n + 1) / 2 - count);
                        }
                    }
                    count = 1;
                }
            }

            if(ans == -1){
                for(int val : map.values()){
                    if(val >= (n + 1) / 2) ans = (n + 1) / 2;
                }
            }
            System.out.println(ans);
        }
    }
}

第四题 数学竞赛

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNextLine()){
            String[] line = input.nextLine().split(" ");
            int n = Integer.parseInt(line[0]), k = Integer.parseInt(line[1]);
            int[] nums = new int[n];
            line = input.nextLine().split(" ");
            for(int i = 0; i < n; ++i) nums[i] = Integer.parseInt(line[i]);

            Map<Integer, List<Integer>> map = new HashMap<>();
            for(int i = 0; i < n; ++i){
                List<Integer> temp = map.getOrDefault(nums[i], new ArrayList<>());
                temp.add(i + 1);
                temp.sort((o1, o2) -> o1 - o2);
                map.put(nums[i], temp);
            }
            List<Integer> test = new ArrayList<>(), train = new ArrayList<>();
            for(int key : map.keySet()){
                List<Integer> arr = map.get(key);
                int size = arr.size();
                for(int i = 0; i < size; ++i){
                    if(i < (size + 1) / 2) train.add(arr.get(i));
                    else test.add(arr.get(i));
                }
            }
            test.sort((o1, o2) -> o1 - o2);
            train.sort((o1, o2) -> o1 - o2);

            for(int num : train) System.out.print(num + " ");
            System.out.println();
            for(int num : test) System.out.print(num + " ");
        }
    }

}

附加题 第K个数字

字符串的表示为 [source][rever][wow],三个部分
解题思路:使用字符串模拟,估计不是内存溢出,就是时间超时

  • 采用 index,和 len 去模拟字符串,根据 index 和 len 的关系,不断去缩小范围知道 index 在MeiTuannauTieMwow 这个字符串长度内

    • 如果 len - index < 3,那么刚坐标处于 "wow"结尾中

    • 如果 index > (len - 3) /2 ,那么index 处于 rever 这个范围中

    • 如果 index < (len - 3) / 2,那么index 处于 source这个返回中

    • 如果 index < "MeiTuannauTieMwow".length,那么直接返回

      public class Main {
      public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = Integer.parseInt(input.nextLine());
        while (n -- > 0){
            long target = Long.parseLong(input.nextLine());
      
            String str = "MeiTuannauTieMwow";
            long len = str.length();
      
            long index = target;
            while (index > len){
                len = len * 2 + 3;
            }
      
            while (true){
                if(len - index < 3) {
                    System.out.println("wow".charAt((int)(len - index)));
                    break;
                }else if(index <= str.length()){
                    System.out.println(str.charAt((int)(index - 1)));
                    break;
                }else if(index > (len - 3) / 2){
                    index = len - 3 - index + 1;
                    len = (len - 3) / 2;
                }else{
                    len = (len - 3) / 2;
                }
            }
        }
      }
      }
#美团笔试##美团招聘#
全部评论
第五题哪有那么🤣 public static void main(String[] args) {         Scanner sc = new Scanner(System.in);         String s1 = "MeiTuannauTieMwowwow";         long n = sc.nextLong();         for (long i = 0; i < n; i++) {             long k=sc.nextLong()-1;             k %= 20;             System.out.println(s1.charAt((int) k));         }     }
2 回复 分享
发布于 2022-08-06 15:28
第一题直接min(min(a,b),(a+b)/3))就行了
1 回复 分享
发布于 2022-08-06 17:51
魔法石那题,不是只能把原本是反面的摆为正面吗?怎么还有第二种情况呀
1 回复 分享
发布于 2022-08-06 14:22
第一题里面,为啥不满足的话直接两数相加除3就行呢,有点没理解
1 回复 分享
发布于 2022-08-06 14:09
牛的
1 回复 分享
发布于 2022-08-06 13:24
佬已经oc了吗
点赞 回复 分享
发布于 2022-09-11 12:28 北京
int l = i == 0 ? 0 : left[i - 1];这里为什么是i-1呀
点赞 回复 分享
发布于 2022-08-09 10:14
美团内推找我哦,帮查进度😁,内推码ACfgTAb
点赞 回复 分享
发布于 2022-08-08 15:07
这是提前批嘛
点赞 回复 分享
发布于 2022-08-08 12:54
点赞 回复 分享
发布于 2022-08-08 11:23
第五题的抽象美如画,感谢分享,学习了
点赞 回复 分享
发布于 2022-08-08 10:16
强!
点赞 回复 分享
发布于 2022-08-07 13:42
第二题暴力法求解,是没考虑到什么内容吗?求教😫
点赞 回复 分享
发布于 2022-08-07 11:04
不是吧,这么难?没有力扣改编题吗😣
点赞 回复 分享
发布于 2022-08-07 10:14
大佬,第二题中: left数组表示的是:i左边(包括i)大于等于0的数量 right数组表示的是:i右边(包括i)小于等于0的数量 是这样嘛?
点赞 回复 分享
发布于 2022-08-06 18:00
点赞 回复 分享
发布于 2022-08-06 17:31
牛的
点赞 回复 分享
发布于 2022-08-06 16:02
魔法石那题,这种情况[[1,1,2,2,2,4,5,6],[3,3,1,1,3,5,4,7]],魔法阵1在每一行都不是最多的,但最后选择的是魔法阵1
点赞 回复 分享
发布于 2022-08-06 14:40
大佬,第一题里面( A + B) / 3  是什么思想?可以说一下吗。
点赞 回复 分享
发布于 2022-08-06 14:11
牛牛牛
点赞 回复 分享
发布于 2022-08-06 14:08

相关推荐

想run的马里奥在学...:这个学历帮你扫平百分之80的障碍,投就完了,这会找不到就等3月暑期一样能找到
点赞 评论 收藏
分享
昨天 00:12
已编辑
香港大学 Java
这里没熟人,吐槽一下吧,楼主语文不太好,语句可能不太通顺,想到哪说到哪。我只想说字节,你太狠了。。。作为一个校招生,字节landing实在是地狱级别,来到字节已经一个月了,在这一个月里,每天都承受着巨大的压力,每天起床感觉胸闷气短,饭也吃不下,一个月已经瘦了五六斤了(也算是变相减肥了),一想到上班就莫名其妙地喘不过气来,闭上眼脑子里都是代码。压力一方面来自于mt的压力,一方面是自己的压力。我参与的项目是几个月的新项目,项目很多不完善的地方,业务流程不完善,很多代码需要根据做产品的需求做大改动,而楼主从来没有做过业务方面的编码,所以在理解业务需求的时候,非常难受,而且业务线很长,作为承接上下游的中间系统,不仅要了解自己项目的流程,还要了解上下游的流程,导致上手非常困难,也有可能是楼主太菜了QAQ。。楼主12.17入职,一周之内就已经开始做需求了,第一个需求就是新增和修改数据,mt美名其曰给我练手,但是一个小小的新增和修改涉及了太多细节,在字段定义不明确、数据来源不了解、处理流程不清晰的情况下,楼主花了一周时间完成了这个需求,当然做技术方案评审的时候,被吊了好几次,修改了几版方案。需求做完,被测试找出来十几个缺陷,每天不是在修bug,就是在修bug的路上,修bug修的精疲力尽,每天自测都需要花费很长时间,导致lz每天都十分紧张,不敢打开飞书,生怕又收到QA的信息,并且产品设计及其粗糙,很多地方都需要再三确认,严重拖慢进度。好不容易做完还被嫌进度太慢,下一个需求就让我开天辟地,完成整个业务流程的编码,lz真的直冒汗啊啊啊,真把我当老员工对待啊。最重要的一点,mt从来不给正反馈,每次问问题都会被反问,这个流程你真的理解了么,这个需求你认真思考了么,站在用户角度思考了么,站在产品角度思考了么,站在前端角度思考了么,站在QA角度思考了么,总之得不到什么有用的回复,每次问问题都是煎熬,从来得不到肯定的回复,要不就是反问,要不就是让lz去问产品,去和其他人对齐,每次都不被肯定的滋味真的很难受,导致lz现在不敢问问题,生怕再被吊,真的难受啊啊。顺便说一嘴,字节的福利是真的好,饭菜也很好吃(虽然我不大能吃得下)。今天11点刚到家,洗漱完上床已经快12点了,今天先写到这里吧,给自己留半小时抖音时间,毕竟只有睡前的时间是属于自己的。世界是个巨大的围城,有人想进来,有人想出去,不正真体验过不知道自己想要的到底是什么。。加油吧。
喵_coding:唉 进不去的挤破头都想进去 进去了的又真觉得很累 这个世界究竟怎么了
工作压力大怎么缓解
点赞 评论 收藏
分享
评论
23
146
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务