大厂2021届秋招试题集

本文汇总了2021年百度、美团和字节跳动三家大厂的校园招聘秋招笔试算法题目,包括题目描述、解题思路和样例。内容涉及多关键字排序、棋盘游戏计分、六位数问题、新游戏策略、找朋友子序列等算法挑战,适合准备面试的程序员练习。
摘要由CSDN通过智能技术生成

百度2021届校园招聘秋招笔试题

题1,李华的礼物

题目描述:

李华顺利地到达了巴黎,他的好友 Peter 带他开启了他的巴黎之旅。途中,李华遇到了许多心动的纪念品想要带回家,但是他又不想自己太累,而且他买纪念品也有相应的预算 k,现给出他心动的纪念品清单:共有 n 件,其中每件都各有其价格 price,重量 weight,心动值 v (其中心动值为1~5之间的数值),需要注意的是:在心动值不同的情况下,李华会优先选择心动值大的纪念品;若心动值相同,李华会优先选择比较便宜的纪念品,具体见样例。同时给出李华在保证不累的情况下,最多能拿的物品重量 m。在不超过预算并且保证不累的情况下,李华最多可以带几件纪念品回家?

输入描述:

单组输入。
第1行三个正整数,分别为:纪念品件数 n,最多能拿的物品重量 m,预算 k。(n<1e5,m<100,k<10000,k 的单位为元,m 的重量为 kg

第2行到第 n+1 行,分别为每件物品的价格 price,重量 weight,心动值 v。(price<10000,weight<100v 为1~5之间的整数,price 的单位为元,weight 的重量为 kg

输出描述:

在不超过预算并且保证不累的情况下,李华最多可以带回家的纪念品件数。

样例输入:

3 10 1000
100 5 3
50 3 2
300 3 3

样例输出:

2

解释:

李华会优先选择心动值较大的礼物1,3,且总重量和预算都没超过,所以输出为2。

思路分析

其实想明白了挺简单的,当时感觉真脑子短路了。优先按心动值降序,然后心动值相同按照价格升序,考察的核心就是多关键字排序问题。

代码如下:

package com.exam;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

/**
 * 样例输入:
 * 3 10 1000
 * 100 5 3
 * 50 3 2
 * 300 3 3
 *
 * 样例输出:
 * 2
 *
 * @author zhangbocheng
 * @version v1.0
 * @date 2020/9/4 11:50
 */
public class BaiduGift {
   

    public static void main(String[] args) {
   
        Scanner sc = new Scanner(System.in);
        String[] row = sc.nextLine().split(" ");
        // 礼物行数
        int n = Integer.parseInt(row[0]);
        // 可承受的总重量
        int m = Integer.parseInt(row[1]);
        // 总预算
        int k = Integer.parseInt(row[2]);

        // 构造礼物矩阵
        List<Gift> giftArray = new ArrayList<>(16);
        while (n > 0) {
   
            String[] items = sc.nextLine().split(" ");
            Gift gift = new Gift();
            gift.setPrice(Integer.parseInt(items[0]));
            gift.setWeight(Integer.parseInt(items[1]));
            gift.setV(Integer.parseInt(items[2]));
            giftArray.add(gift);
            n--;
        }

        System.out.println(getGiftNumber(giftArray, m, k));
    }

    private static int getGiftNumber(List<Gift> giftArray, int m, int k) {
   
       List<Gift> gifts = giftArray.stream()
               .sorted(Comparator.comparing(Gift::getV).reversed()
                       .thenComparing(Gift::getPrice)).collect(Collectors.toList());
       int count = 0;
       for (Gift gift: gifts) {
   
            m -= gift.getWeight();
            k -= gift.getPrice();
            if (m < 0 || k < 0) {
   
                break;
            }
            count++;
            // 验证
            System.out.printf("%d\t%d\t%d\n", gift.getPrice(), gift.getWeight(), gift.getV());
        }

       return count;
    }

    static class Gift {
   
        /**
         * 价格
         */
        private int price;
        /**
         * 重量
         */
        private int weight;
        /**
         * 心动值
         */
        private int v;

        public int getPrice() {
   
            return price;
        }

        public void setPrice(int price) {
   
            this.price = price;
        }

        public int getWeight() {
   
            return weight;
        }

        public void setWeight(int weight) {
   
            this.weight = weight;
        }

        public int getV() {
   
            return v;
        }

        public void setV(int v) {
   
            this.v = v;
        }
    }
}

题2,最小计分

题目描述:

小度最近在研究一个棋盘游戏,游戏规则如下:

一个 N ∗ N N*N NN 的棋盘,每个格子里面填写有1、2、3、4这四个数字中的某一个。最开始时在第1行第1列(左上角)放置一个棋子。每次棋子可以移动至上、下、左、右四个格子中的某一个,每次只能移动一格(允许重复移动到某一个格子),在任何时刻都不允许将棋子移出棋盘。在移动时需要进行计分。如果初始格子中的数字为 X X X,目标格子中的数字为 Y Y Y,则本次移动计分为 ∣ X − Y ∣ |X-Y| X

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值