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