每日一题:小C的回文博弈(青训营X豆包MarsCode) | 豆包MarsCode AI 刷题

162 阅读3分钟

小C的回文博弈

小C和小U在一场激烈的回文博弈中展开对决。游戏从一个初始字符串s开始,规则如下:

  1. 每个玩家轮流行动,每次行动都可以重新排列字符串。
  2. 如果通过重新排列能够形成一个回文串,游戏立即结束,当前玩家获胜。
  3. 如果无法形成回文串,玩家必须删除字符串中的一个字符,游戏继续。

小C总是先手,两人都使用最优策略,最终谁将赢得这场比赛呢?如果小C获胜则输出"C",小U获胜则输出"U"


测试样例

样例1:

输入:s = "aab"
输出:'C'

样例2:

输入:s = "abc"
输出:'C'

样例3:

输入:s = "abcd"
输出:'U'

在这场回文博弈中,游戏的规则和双方的策略是关键。让我们来分析解决方法:

  1. 判断是否可以构成回文:在一个字符串中,如果字符的个数为奇数的字符数不超过1个,就可以通过重新排列构成一个回文。
  2. 删除字符的策略
    • 每轮游戏中,若当前字符串可以重新排列成回文,则当前玩家获胜。
    • 若不行,当前玩家删除一个字符后,将局面交给对手。
  1. 博弈分析
    • 小C先手,且双方都采用最优策略。
    • 如果字符串初始就可以构成回文,小C直接获胜。
    • 若不行,游戏的关键在于删除字符的顺序以及字符串的长度变化。特别地,如果游戏进入字符串长度为1的局面,则小C获胜(先手优势)。

我们可以推导出一个解决方案,通过奇数个字符的个数判断是否可以直接构成回文,或者在博弈过程中谁会获胜。

代码实现

def solution(s: str) -> str:
    from collections import Counter

    # 统计每个字符出现的次数
    count = Counter(s)
    odd_count = sum(1 for freq in count.values() if freq % 2 == 1)
    
    # 如果奇数个字符的个数小于等于1,小C可以直接通过重排获胜
    if odd_count <= 1:
        return 'C'
    
    # 如果奇数个字符的个数超过1,则需要删除字符,轮流操作。
    # 奇数个奇数字符 -> 小C最终获胜,因为先手优势。
    # 偶数个奇数字符 -> 小U最终获胜。
    if odd_count % 2 == 1:
        return 'C'
    else:
        return 'U'

代码解释

  1. 计数和奇数判断:使用 Counter 来统计每个字符的频次,然后统计频次为奇数的字符数 odd_count
  2. 直接获胜条件:如果 odd_count 小于等于1,小C可以直接重排获胜。
  3. 轮流删除分析
  • 如果 odd_count 是奇数,小C最终获胜。
  • 如果 odd_count 是偶数,小U最终获胜。

总结归纳

  • 总结解题方法:做完一道题后,使用 Marscode 总结该题的解题方法,提炼出通用的思路和技巧,以便在遇到类似题目时能够快速上手。例如, “小 C 的回文博弈” 总结其通过判断奇数个字符个数来解题的方法。
  • 归纳常见错误:回顾解题过程中出现的错误,如在 “小 C 的回文博弈” 中可能出现对规则理解错误导致判断获胜条件有误等情况。使用 Marscode 刷题时,将常见错误进行归纳整理,提醒自己在后续做题中避免再次犯错。