问题描述
小U和
n个小朋友正在玩一个有趣的糖果传递游戏。n个小朋友按顺序排成一列,小U站在最右边的位置。游戏开始时,小U为每个小朋友分配了a[1], a[2], ..., a[n]个糖果。现在,小U手里还剩下m个糖果要分配。分配规则如下:
- 每个糖果都会先从第一个小朋友开始分配。如果当前小朋友的糖果数量(包括新分配的糖果)小于或等于他的右边的小朋友,则他会保留这个糖果。
- 如果当前小朋友的糖果数量大于他右边的小朋友,他会将这个糖果传递给下一个小朋友。
- 这个过程会持续,直到糖果传递到第
n个小朋友。如果第n个小朋友也不能保留这个糖果,那么糖果会被传递给小U。现在,请你帮忙确定第
m个糖果最终会分配给哪个小朋友,或者传递给小U。
算法思路总结
-
初始化:
- 创建一个长度为
n+1的数组a_,其中前n个元素复制自输入数组a,最后一个元素a_[n]初始化为m,表示剩余的糖果数量。(这一步或许有更优雅的实现方法,可以直接使用 System.arraycopy 来复制数组,或者使用 Arrays.copyOf。)
- 创建一个长度为
-
分配糖果:
- 使用一个
while循环,只要a_[n](剩余糖果数量)大于 0,就继续分配糖果。 - 在
while循环内部,使用一个for循环遍历每个小朋友(从第一个到第n-1个)。 - 对于每个小朋友,检查如果他接收一个糖果后,糖果数量是否仍然小于或等于他右边的小朋友。如果是,则将糖果分配给他,并更新
a_[n](剩余糖果数量)。 - 如果当前小朋友不能接收糖果(即他的糖果数量大于右边的小朋友),则继续检查下一个小朋友。
- 如果所有小朋友都不能接收糖果,则将糖果传递给小U,并更新
a_[n](剩余糖果数量)。
- 使用一个
-
返回结果:
- 最终返回
sugerend,表示最后一个糖果分配给的小朋友的编号,或者如果传递给小U,则返回n+1。
- 最终返回
关键点
数组 a_ 的使用:
a_数组用于存储每个小朋友的糖果数量,最后一个元素a_[n]用于记录剩余的糖果数量。
双重循环:
while循环用于控制糖果分配的总体过程。for循环用于遍历每个小朋友,尝试将糖果分配给他。
条件判断:
- 在
for循环中,通过条件判断决定糖果是否分配给当前小朋友,或者传递给下一个小朋友。
代码实现:
public class Main {
public static int solution(int n, int m, int[] a) {
// Edit your code here
int sugerend = 0;
int[] a_ = new int[n + 1];
for (int i = 0; i < a.length; i++) {
a_[i] = a[i];
}
a_[n] = m;
while (a_[n] > 0) {
for (int i = 0; i < n; i++) {
if (a_[i] + 1 <= a_[i + 1]) {
a_[i] += 1;
sugerend = i + 1;
a_[n] -= 1;
break;
}
if (i == n - 1) {
sugerend = n + 1;
a_[n] -= 1;
break;
}
}
// System.err.println(a_[n]);
}
// System.err.println("result=" + sugerend);
return sugerend;
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(solution(4, 3, new int[] { 1, 2, 3, 4 }) == 1);
System.out.println(solution(4, 2, new int[] { 4, 3, 2, 3 }) == 5);
// solution(4, 2, new int[] { 4, 3, 2, 3 });
}
}