题目描述
shopee的零食柜,有着各式各样的零食,但是因为贪吃,小虾同学体重日益增加,终于被人叫为小胖了,他终于下定决心减肥了,他决定每天晚上去操场跑两圈,但是跑步太累人了,他想转移注意力,忘记痛苦,正在听着音乐的他,突然有个想法,他想跟着音乐的节奏来跑步,音乐有7种音符,对应的是1到7,那么他对应的步长就可以是1-7分米,这样的话他就可以转移注意力了,但是他想保持自己跑步的速度,在规定时间m分钟跑完。为了避免被累死,他需要规划他每分钟需要跑过的音符,这些音符的步长总和要尽量小。下面是小虾同学听的歌曲的音符,以及规定的时间,你能告诉他每分钟他应该跑多少步长?
题解代码
作者:Cantwell
链接:https://www.nowcoder.com/questionTerminal/24a1bb82b3784f86babec24e4a5c93e0
来源:牛客网
import java.util.Scanner;
/**
* Shopee的零食柜
* https://www.nowcoder.com/questionTerminal/24a1bb82b3784f86babec24e4a5c93e0
*/
public class ShopeeSnacksArk {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] arr = new int[n];
// 最大的一步
int left = -1;
// 总步数
int right = 0;
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
left = Math.max(left, arr[i]);
right += arr[i];
}
while (left < right) {
int mid = (left + right) >> 1;
int cmp = check(arr, mid, m);
if (cmp == -1) {
// 花费时间小于m,应缩小step
right = mid - 1;
} else if (cmp == 1) {
// 花费时间大于m,应增大step
left = mid + 1;
} else {
// 进一步缩小step
right = mid;
}
}
System.out.println(left);
sc.close();
}
// 每分钟走step步,若花费时间小于m分钟,返回-1,若相等,返回零,若大于,返回1
private static int check(int[] arr, int step, int m) {
int sum = 0;
int num = 1;
for (int value : arr) {
if (sum + value <= step) {
sum += value;
} else {
sum = value;
num++;
}
}
return Integer.compare(num, m);
}
}