【Python实现】Alice, Bob 和巧克力问题详解

一、题目背景

Alice 和 Bob 是一对喜欢玩游戏的朋友。他们现在准备玩一个新的游戏:巧克力分配游戏。在游戏中,有 nn 块巧克力排成一排。Alice 从左到右开始吃巧克力,而 Bob 从右到左开始吃巧克力。

对于每块巧克力,已知 Alice 或 Bob 吃掉它所需要的时间 tit_i。当玩家吃掉一块巧克力后,他们会立即开始吃下一块巧克力。为了保证公平:

  1. 同一时间不能同时吃两块巧克力;
  2. 如果两人同时吃到同一块巧克力,Bob会让给 Alice。

题目的目标是:根据这些规则,计算 Alice 和 Bob 各自吃掉的巧克力数量。


二、题目描述

输入

  • 第一行包含一个整数 nn (1≤n≤105)(1 \leq n \leq 10^5) ------ 巧克力的数量。
  • 第二行包含 nn 个整数 t1,t2,...,tnt_1, t_2, \ldots, t_n (1≤ti≤1000)(1 \leq t_i \leq 1000),其中 tit_i 是吃掉第 ii 块巧克力所需的时间。

输出

输出两个整数 aa 和 bb,分别表示 Alice 和 Bob 各自吃掉的巧克力数量。

示例

输入

5
2 9 8 7 2

输出

2 3

解释

  • Alice 从左到右吃巧克力,消耗的时间依次为 2, 9
  • Bob 从右到左吃巧克力,消耗的时间依次为 2, 7, 8
  • 总共有 5 块巧克力,其中 Alice 吃了 2 块,Bob 吃了 3 块。

三、解题思路

我们可以模拟 Alice 和 Bob 各自的吃巧克力过程,按以下规则分配巧克力:

  1. 定义两个指针,left 指向最左侧的巧克力,right 指向最右侧的巧克力。
  2. 分别定义 Alice 和 Bob 的总消耗时间变量 alice_timebob_time,初始值为 0。
  3. Alice 每次优先选择 left 位置的巧克力,并将时间加到 alice_time;Bob 优先选择 right 位置的巧克力,并将时间加到 bob_time
  4. 根据以下规则移动指针:
    • 如果 alice_time <= bob_time,则 Alice 继续选择 left 位置,left 指针右移。
    • 否则,Bob 选择 right 位置,right 指针左移。
  5. 当两个指针相遇时,根据总时间决定最终归属。

通过上述规则,我们可以准确计算 Alice 和 Bob 吃掉的巧克力数量。


四、Python实现

以下是完整的 Python 实现代码:

def alice_bob_chocolates():
    # 读取输入
    n = int(input())  # 巧克力数量
    times = list(map(int, input().split()))  # 每块巧克力所需时间
    
    # 初始化变量
    left, right = 0, n - 1
    alice_time, bob_time = 0, 0
    alice_count, bob_count = 0, 0

    # 模拟分配巧克力的过程
    while left <= right:
        if alice_time <= bob_time:
            alice_time += times[left]
            alice_count += 1
            left += 1
        else:
            bob_time += times[right]
            bob_count += 1
            right -= 1
    
    # 输出 Alice 和 Bob 吃掉的巧克力数量
    print(alice_count, bob_count)

# 调用主函数
if __name__ == "__main__":
    alice_bob_chocolates()

五、代码详解

1. 输入读取与初始化

n = int(input())  # 巧克力数量
times = list(map(int, input().split()))  # 每块巧克力所需时间

我们使用 input() 读取输入数据:

  • 第一行是整数 nn,表示巧克力数量;
  • 第二行是一个整数数组,表示每块巧克力的消耗时间。

2. 模拟分配过程

left, right = 0, n - 1
alice_time, bob_time = 0, 0
alice_count, bob_count = 0, 0

通过定义两个指针 leftright 分别指向巧克力的最左端和最右端。我们还定义了 Alice 和 Bob 的时间变量 alice_timebob_time,以及各自吃掉的巧克力数量变量 alice_countbob_count

主循环模拟两人轮流吃巧克力的过程:

while left <= right:
    if alice_time <= bob_time:
        alice_time += times[left]
        alice_count += 1
        left += 1
    else:
        bob_time += times[right]
        bob_count += 1
        right -= 1
  • 如果 Alice 的总消耗时间小于等于 Bob 的时间,Alice 吃掉 left 指针位置的巧克力,并将 left 指针右移。
  • 否则,Bob 吃掉 right 指针位置的巧克力,并将 right 指针左移。

3. 输出结果

print(alice_count, bob_count)

最后输出 Alice 和 Bob 吃掉的巧克力数量。


六、复杂度分析

  1. 时间复杂度

    • 主循环中,每次移动一个指针(leftright),总共最多移动 nn 次。
    • 因此,时间复杂度为 O(n)O(n)。
  2. 空间复杂度

    • 仅使用了常数个额外变量(如 left, right 等),空间复杂度为 O(1)O(1)。

七、测试用例

我们通过以下几个测试用例验证代码的正确性:

测试用例 1

输入

5
2 9 8 7 2

输出

2 3

解释 : Alice 吃了 2, 9;Bob 吃了 2, 7, 8


测试用例 2

输入

4
1 2 3 4

输出

2 2

解释 : Alice 吃了 1, 2;Bob 吃了 4, 3


测试用例 3

输入

6
1 1 1 1 1 1

输出

3 3

解释: Alice 和 Bob 各吃掉 3 块巧克力。


八、总结

本问题考察了双指针算法的应用,同时涉及到贪心策略的设计。通过维护两个时间变量,我们可以高效地模拟 Alice 和 Bob 吃巧克力的过程。代码逻辑清晰、运行效率高,非常适合用于大规模数据处理。

希望这篇文章对你有所帮助!如果觉得有用,欢迎点赞、收藏和评论~


相关推荐
咩咩觉主几秒前
C# &Unity 唐老狮 No.7 模拟面试题
开发语言·unity·c#
大丈夫在世当日食一鲲1 分钟前
Java中用到的设计模式
java·开发语言·设计模式
DanCheng-studio5 分钟前
智科 机器学习毕业设计题目指导
python·毕业设计·毕设
却道天凉_好个秋31 分钟前
c++ 嵌入汇编的方式实现int型自增
开发语言·汇编·c++
java1234_小锋1 小时前
一周学会Flask3 Python Web开发-SQLAlchemy定义数据库模型
python·flask·sqlalchemy·flask3
33三 三like1 小时前
软件工程画图题
java·开发语言·软件工程
Light601 小时前
CSnakes vs Python.NET:跨语言集成的巅峰对决与架构解密
python·性能优化·.net·跨语言集成·双向互操作
&岁月不待人&1 小时前
Kotlin和Java区别
java·开发语言·kotlin
gallonyin1 小时前
免root运行python保活守护进程supervisor
linux·开发语言·python
lisw052 小时前
【PyCharm】Python和PyCharm的相互关系和使用联动介绍
ide·python·pycharm