Leetcode 1908. Nim 游戏 II

1.题目基本信息

1.1.题目描述

Alice 和 Bob 交替进行一个游戏,由 Alice 先手。

在游戏中,共有 n 堆石头。在每个玩家的回合中,玩家需要 选择 任一非空石头堆,从中移除任意 非零 数量的石头。如果不能移除任意的石头,就输掉游戏,同时另一人获胜。

给定一个整数数组 piles ,piles[i] 为 第 i 堆石头的数量,如果 Alice 能获胜返回 true ,反之返回 false 。

Alice 和 Bob 都会采取 最优策略 。

1.2.题目地址

https://leetcode.cn/problems/game-of-nim/description/

2.解题方法

2.1.解题思路

SG函数 / 记忆化搜索 / 公式

2.2.解题步骤

公式证明:

命题:如果nim游戏先手选择时的石子堆数为[a1,a2,...,an],如果x=a1^a2^...^an=0,则先手必败,如果x!=0,则必胜

证明1(x!=0,则先手必胜):

  • 假设当前的状态x=a1^a2^...^an,设x的二进制最高位为k,那么一定存在一个ai,其二进制的第k位为1,由异或的运算规律可知,ai^x<ai(ai^x的最高位被异或没了,但是ai二进制最高位还在),现在从ai中挑选出若干个,使ai变成ai^x,此时的x=a1^a2^...^ai^x^...^an=0(异或的交换律),所以一定存在一个选择方式,使后手处于必败态(即x==0)

证明2:(x==0,则后手必败)(反证)

  • 假设当前的状态x=a1^a2^...^an=0,假设存在一个选择方法,使ai变成bi(ai>bi),且x2=a1^a2^...^bi^...^an=0;则x^x2=ai^bi=0,即ai==bi,这和ai>bi假设冲突,所以推翻假设,即不存在一个选择方法,使选择后的x!=0,得证

3.解题代码

python代码

# 功能:求集合st第一个不存在的自然数
def mex(st:set) -> int:
    i = 0
    while i in st:
        i += 1
    return i

# 功能:记忆化搜索计算sg值
memo = {}
def sg(x:int) -> int:
    if x not in memo:
        # 1.子游戏中递归出口
        if x == 0:
            return 0
        # 2.子游戏中x状态的下一个状态的sg值集合
        st = set()
        for i in range(x):
            st.add(sg(i))
        memo[x] = mex(st)
    return memo[x]

class Solution:
    def nimGame(self, piles: List[int]) -> bool:
        # 思路:SG函数
        result = 0
        for pile in piles:
            result ^= sg(pile)
        return result != 0

    def nimGame1(self, piles: List[int]) -> bool:
        # 思路:公式
        ans = 0
        for num in piles:
            ans ^= num
        return ans != 0

4.执行结果

<think>好的,我现在需要帮助用户找到关于C语言实现红黑树的在线评测(OJ)题目。首先,我得理解用户的需求。用户可能是在准备考试或者面试,需要练习红黑树的C语言实现,并且希望通过在线评测系统来测试自己的代码。 接下来,我需要回忆一下常见的OJ平台,比如LeetCode、洛谷、HDU等,看看它们是否有相关的题目。但根据我的知识库,LeetCode等主流OJ可能较少直接考察红黑树的实现,因为红黑树属于高级数据结构,通常在实际工程中应用较多,但OJ题目可能更偏向于使用平衡树解决的问题,比如Treap或AVL树,或者直接使用标准库中的结构。 不过,用户明确提到C语言和红黑树,所以可能需要寻找更偏向底层实现的题目。例如,可能需要实现红黑树的插入、删除操作,或者解决与红黑树性质相关的题目。此外,有些大学的OJ可能会有这样的题目,特别是非OJ测评的院校,可能会在考试中涉及链表或树结构的实现,但需要具体例子。 然后,我查看提供的引用内容。引用[1]提到链表类问题对于OJ测评的同学可以用数组实现,但非OJ测评的院校可能会考链表。引用[4]提到平衡树问题,包括treap和树状数组的解法,可能涉及红黑树的相关应用。这可能提示用户,虽然直接的红黑树题目不多,但平衡树相关问题可能可以间接练习,或者某些题目需要红黑树作为解决方案的一部分。 考虑到用户需要C语言的实现,可能需要查找那些要求手动实现红黑树的题目。例如,有些OJ题目可能要求维护一个有序集合,支持高效的插入、删除和查询操作,这时候红黑树是一个合适的底层结构。但这类题目通常不会强制要求使用红黑树,只要效率达标即可,所以用户可能需要寻找明确要求红黑树的题目。 另外,可能需要建议用户参考一些经典的算法书籍或大学课程中的实验题目,这些地方更可能有红黑树的实现任务。例如,MIT的课程项目或《算法导论》中的实现题,虽然不一定是OJ形式,但用户可以通过自己编写测试用例来验证。 最后,整理思路:直接的红黑树OJ题目较少,但可以通过平衡树相关问题进行练习,或者查找特定平台的题目。同时,建议用户查阅大学OJ或教材实验,以及提供红黑树的基本实现要点和注意事项,帮助用户自行练习。</think>### 关于C语言实现红黑树的OJ题目推荐 直接要求实现红黑树的OJ题目较少,但以下方向可能符合你的需求: 1. **平衡树相关问题** 红黑树属于平衡树的一种,可通过解决其他平衡树(如AVL树、Treap)的问题练习相似逻辑[^4]。例如: - **HDU 1908**:实现平衡树操作(插入、删除、查询),可用红黑树完成。 - **POJ 3481**:双队列维护问题,需要高效动态排序能力。 2. **大学实验题或课程OJ** 部分高校的非公开OJ可能包含红黑树实现题,例如: - **实现集合操作**:要求支持插入、删除、查找,并统计中位数/极值。 - **动态排名问题**:维护数据流中的实时排名,需结合红黑树的有序性。 3. **手动实现红黑树的要点**(若无现成OJ题) 可参考以下流程自测: ```c // 红黑树节点定义 typedef struct Node { int key; int color; // 0:黑, 1:红 struct Node *left, *right, *parent; } Node; // 插入修复函数 void fix_insertion(Node **root, Node *z) { // 实现颜色调整与旋转逻辑 } ``` - 测试案例:依次插入{10, 20, 30, 15, 25},验证红黑树性质(如根节点为黑色、无连续红节点等)。 4. **替代方案建议** 多数OJ允许用更简单的结构(如`STL map`或数组)替代红黑树[^1],例如: - **LeetCode 220**:桶排序+滑动窗口可高效解决,无需手动写红黑树。 ### 建议练习路径 1. 先掌握红黑树的插入、删除规则和旋转操作。 2. 尝试实现完整红黑树并通过本地测试用例(如随机插入/删除后验证性质)。 3. 搜索关键词**C语言 红黑树 动态集合** 寻找定制化题目。 ### 注意事项 - 红黑树代码量较大,建议先理解透原理再动手写[^4]。 - 调试时重点关注**双黑修正**和**颜色翻转**的边界条件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Benjamin Tang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值