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

相关推荐

03-15 14:55
已编辑
门头沟学院 golang
bg:双非学院本&nbsp;ACM银&nbsp;go选手timeline:3.1号开始暑期投递3.7号第二家公司离职顽岩科技&nbsp;ai服务中台方向&nbsp;笔试➕两轮面试,二面挂(钱真的好多😭)厦门纳克希科技&nbsp;搞AI的,一面OC猎豹移动&nbsp;搞AIGC方向&nbsp;一面OC北京七牛云&nbsp;搞AI接口方向&nbsp;一面OC上海古德猫宁&nbsp;搞AIGC方向&nbsp;二面OC上海简文&nbsp;面试撞了直接拒深圳图灵&nbsp;搞AIGC方向一面后无消息懒得问了,面试官当场反馈不错其他小厂没记,通过率80%,小厂杀手😂北京字节&nbsp;具体业务不方便透露也是AIGC后端方向2.28约面&nbsp;(不知道怎么捞的我,我也没在别的地方投过字节简历哇)3.6一面&nbsp;一小时&nbsp;半小时拷打简历(主要是AIGC部分)剩余半小时两个看代码猜结果(经典go问题)➕合并二叉树(秒a,但是造case造了10分钟哈哈)一天后约二面3.12&nbsp;二面,让我挑简历上两个亮点说,主要说的docker容器生命周期管理和raft协议使用二分法优化新任leader上任后与follower同步时间。跟面试官有共鸣,面试官还问我docker底层cpu隔离原理和是否知道虚拟显存。之后一道easy算法,(o1空间解决&nbsp;给定字符串含有{和}是否合法)秒a,之后进阶版如何用10台机加快构建,想五分钟后a出来。面试官以为45分钟面试时间,留了18分钟让我跟他随便聊,后面考了linux&nbsp;top和free的部分数据说什么意思(专业对口了只能说,但是当时没答很好)。因为当时手里有7牛云offer,跟面试官说能否快点面试,马上另外一家时间到了。10分钟后约hr面3.13,上午hr面,下午走完流程offer到手3.14腾讯技术运营约面,想直接拒😂感受:&nbsp;因为有AIGC经验所以特别受AI初创公司青睐,AIGC后端感觉竞争很小(指今年),全是简历拷打,基本没有人问我八股(八股吟唱被打断.jpeg),学的东西比较广的同时也能纵向深挖学习,也运气比较好了哈哈可能出于性格原因,没有走主流Java路线,也没有去主动跟着课写项目,项目都是自己研究和写的哈哈
烤点老白薯:你根本不是典型学院本的那种人,贵了你这能力
查看7道真题和解析
点赞 评论 收藏
分享
哈哈哈看得出来讨论很沸腾了,很高兴了属于是&nbsp;大家快说说截止目前还有哪家互联网大厂不是双休?(在说谁,在说谁)一起避坑!!
不正经草莓:听红薯来的同事讲,他们之前周六下午6点多就走了,一天也没啥事儿到手6k多工资,要我也加班查看图片
投递小红书等公司6个岗位 > 小红书取消大小周
点赞 评论 收藏
分享
评论
23
146
分享

创作者周榜

更多
牛客网
牛客企业服务