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

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


相关推荐
金色熊族12 分钟前
win11安装matplotlib过程
python·matplotlib
yi碗汤园16 分钟前
Visual Studio常用的快捷键
开发语言·ide·c#·编辑器·visual studio
Elias不吃糖36 分钟前
NebulaChat:C++ 高并发聊天室服务端
开发语言·c++·redis·sql·项目文档
haofafa40 分钟前
JavaScript性能优化实战
开发语言·javascript·性能优化
帅中的小灰灰1 小时前
C++编程策略设计模式
开发语言·c++·设计模式
O***p6041 小时前
JavaScript增强现实开发
开发语言·javascript·ar
Antonio9151 小时前
【Swift】Swift基础语法:函数、闭包、枚举、结构体、类与属性
开发语言·swift
csbysj20201 小时前
Vue3 事件处理
开发语言
databook1 小时前
让你的动画“活”过来:Manim 节奏控制指南 (Rate Functions)
后端·python·动效
Q***f6351 小时前
Kotlin在Android性能优化中的工具
android·开发语言·kotlin