【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 吃巧克力的过程。代码逻辑清晰、运行效率高,非常适合用于大规模数据处理。

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


相关推荐
ascarl20107 分钟前
准确--k8s cgroup问题排查
java·开发语言
互联网杂货铺23 分钟前
完美搭建appium自动化环境
自动化测试·软件测试·python·测试工具·职场和发展·appium·测试用例
Gyoku Mint41 分钟前
机器学习×第二卷:概念下篇——她不再只是模仿,而是开始决定怎么靠近你
人工智能·python·算法·机器学习·pandas·ai编程·matplotlib
fpcc1 小时前
跟我学c++中级篇——理解类型推导和C++不同版本的支持
开发语言·c++
莱茵菜苗1 小时前
Python打卡训练营day46——2025.06.06
开发语言·python
爱学习的小道长1 小时前
Python 构建法律DeepSeek RAG
开发语言·python
luojiaao2 小时前
【Python工具开发】k3q_arxml 简单但是非常好用的arxml编辑器,可以称为arxml杀手包
开发语言·python·编辑器
终焉代码2 小时前
STL解析——list的使用
开发语言·c++
SoFlu软件机器人2 小时前
智能生成完整 Java 后端架构,告别手动编写 ControllerServiceDao
java·开发语言·架构
英英_2 小时前
视频爬虫的Python库
开发语言·python·音视频