青训营ai刷题:糖果传递游戏

45 阅读4分钟

这个问题的关键是理解糖果的传递规则,并通过模拟糖果传递过程来确定第 m 个糖果最终会分配给哪个小朋友,或者传递给小U。

问题分析

给定:

  • n:小朋友的数量(小U在最右边)。
  • m:第 m 个糖果。
  • a:一个包含 n 个元素的数组,表示每个小朋友最初获得的糖果数。
  • 传递规则:
    1. 每个糖果从第一个小朋友开始分配,若当前小朋友的糖果数小于等于其右边的小朋友,则保留该糖果。
    2. 如果当前小朋友的糖果数大于右边的小朋友,则将糖果传递给下一个小朋友。
    3. 如果最后一个小朋友也不能保留该糖果,则传递给小U。

思路

  1. 初始化:首先,我们需要知道每个小朋友开始时的糖果数量,通过 a 数组来表示。
  2. 模拟糖果传递:从第一个小朋友开始分配糖果,按照规则判断糖果是否会传递给下一个小朋友。如果当前小朋友能够保留该糖果,则该小朋友获得糖果,否则继续传递。
  3. 传递到最后:当糖果传递到最后一个小朋友时,若他无法保留糖果,则传递给小U。
  4. 结束条件:我们需要根据传递的糖果数量确定最后一个糖果的归属。

具体步骤

  1. 遍历糖果分配过程:
    • 从第1个小朋友开始,分配每个糖果。
    • 每次检查当前小朋友的糖果是否大于右边的小朋友,如果是,则传递。
    • 如果第 m 个糖果传递到某个小朋友时,这个小朋友将获得糖果。
  2. 结束条件:
    • 如果糖果到达最后一个小朋友且该小朋友也不能保留糖果,则返回 0(表示传递给小U)。

代码实现 public class Main {

// 模拟糖果传递的过程
public static int candyGame(int n, int m, int[] a) {
    int[] candies = a.clone(); // 创建糖果数组,避免修改原始数组

    for (int i = 0; i < m; i++) {
        // 遍历糖果分配过程
        boolean distributed = false;

        for (int j = 0; j < n; j++) {
            if (j == n - 1 || candies[j] <= candies[j + 1]) {
                candies[j]++; // 当前小朋友得到一个糖果
                distributed = true;
                break;
            } else {
                // 否则糖果传递给下一个小朋友
                candies[j + 1]++;
            }
        }
        
        if (!distributed) {
            return 0; // 传递到最后小朋友后传递给小U
        }
    }
    
    // 遍历判断哪个小朋友最后获得糖果
    for (int j = 0; j < n; j++) {
        if (candies[j] > a[j]) {
            return j + 1; // 返回1-based index
        }
    }
    
    return 0; // 如果没有任何小朋友获得糖果,传递给小U
}

public static void main(String[] args) {

// Add your testcases here
  System.out.printin(solution (n: 4, m:3new intlL.2.3.4}) == 1);
  System.out.printin(solution (n: 4, m:2new int[]{4, 3, 2, 3})== 5);

} }

代码解释

  1. candyGame 方法:

    • 创建一个克隆的数组 candies,用来存储每个小朋友的糖果数量。
    • 通过一个循环模拟每个糖果的分配过程。在每个糖果分配时,我们会遍历所有小朋友,根据糖果分配规则来判断哪个小朋友保留糖果或传递给下一个。
    • 如果糖果最终传递到最后一个小朋友并且他不能保留,则糖果被传递给小U,返回 0
    • 如果某个小朋友保留了糖果,返回该小朋友的编号(注意是从1开始)。
  2. 主函数 main

    • 用来测试 candyGame 方法,输出结果。

测试案例

测试案例1 输入:n = 4, m = 3, a = [1, 2, 3, 4] 输出:1 解释:

  • 第1个糖果分配给第1个小朋友。
  • 第2个糖果分配给第1个小朋友。
  • 第3个糖果分配给第1个小朋友。

测试案例2 输入: n = 5, m = 7, a = [1, 2, 3, 4, 5] 输出:2 解释:

  • 通过模拟糖果的分配,最终第7个糖果会被分配给第2个小朋友。

时间复杂度

  • 时间复杂度:O(m * n),因为我们需要模拟每个糖果的分配过程,每个糖果的分配涉及遍历 n 个小朋友。
  • 空间复杂度:O(n),因为我们创建了一个与小朋友数量 n 相同的数组来存储糖果数量。

总结

通过模拟糖果的传递过程,我们可以确定第 m 个糖果最终被哪个小朋友获得或者传递给小U。这个问题考察了如何通过遍历和条件判断来模拟一个简单的游戏过程。