时尚圈的衣着稳定性问题 | 豆包MarsCode AI 刷题

132 阅读4分钟

题目解析

问题描述

小U在时尚圈组织了一场“校服日”活动,有 n 名学生围成一圈参加活动。每位学生都穿着白色或黑色的校服,白色用 0 表示,黑色用 1 表示。每一天,如果某个学生发现自己和相邻的两位学生穿着相同颜色的校服,那么他会在第二天更换成另一种颜色的校服;否则,他会保持不变。

你的任务是帮助小U判断,在第几天学生们的穿着会达到稳定状态——即某一天后,所有学生的穿着不再发生任何变化。同时,你还需要计算在稳定后,有多少学生的校服颜色与其相邻的同学不同,这些学生被称为“时尚达人”。

最终你需要返回一个包含两个元素的数组:

  • 第一个数字表示稳定下来的天数。如果永远无法稳定,则输出 -1
  • 第二个数字表示稳定后成为“时尚达人”的学生人数。如果永远无法稳定,则输出 -1

思路

  1. 初始状态

    • 将输入的字符串转换为列表,方便后续操作。
    • 记录初始状态,并使用集合记录出现过的状态,以检测是否进入循环。
  2. 模拟每一天的变化

    • 遍历每个学生,检查他们是否需要更换校服颜色。
    • 如果当前学生和相邻学生颜色相同,则更换颜色;否则保持不变。
  3. 检测稳定状态

    • 如果下一天的状态与当前状态相同,则说明状态已经稳定。
    • 计算稳定后的时尚达人数量。
  4. 检测循环

    • 如果状态重复出现,说明进入循环,返回 [-1, -1]
  5. 最大步数限制

    • 理论上,超过 2n 步数必定重复,设置一个最大步数限制以避免无限循环。

图解

假设 n = 4,初始状态为 "1110"

  • 第0天1110
  • 第1天0001(所有学生都更换颜色)
  • 第2天1110(所有学生都更换颜色,回到初始状态)

此时状态重复,进入循环,返回 [-1, -1]

代码详解

    # 将初始状态保存
    current_state = list(map(int, data))
    seen_states = set()  # 记录出现过的状态
    days = 0  # 记录天数

    while True:
        # 将当前状态加入已见状态集合
        state_tuple = tuple(current_state)
        if state_tuple in seen_states:
            return [-1, -1]  # 状态重复,进入循环
        seen_states.add(state_tuple)

        days += 1
        next_state = current_state[:]

        # 遍历每个学生更新下一天的状态
        for i in range(n):
            # 获取左右邻居(环形处理)
            left = current_state[(i - 1) % n]
            right = current_state[(i + 1) % n]

            # 判断是否需要改变颜色
            if current_state[i] == left == right:
                next_state[i] = 1 - current_state[i]  # 改变颜色

        # 判断是否稳定
        if next_state == current_state:
            # 稳定后计算时尚达人数量
            fashionistas = 0
            for i in range(n):
                left = next_state[(i - 1) % n]
                right = next_state[(i + 1) % n]
                if next_state[i] != left or next_state[i] != right:
                    fashionistas += 1
            return [days, fashionistas]

        # 更新状态
        current_state = next_state

        # 设置一个最大步数限制(理论上,超过 2n 必定重复)
        if days > 2 * n:
            return [-1, -1]


if __name__ == "__main__":
    # Add your test cases here
    print(solution(4, "0000") == [-1, -1])
    print(solution(4, "1110") == [2, 4])
    print(solution(6, "010101") == [1, 6])

总结

  • 状态模拟:通过模拟每一天的状态变化,逐步逼近稳定状态。
  • 循环检测:使用集合记录出现过的状态,检测是否进入循环。
  • 稳定检测:通过比较当前状态和下一天的状态,判断是否达到稳定。
  • 时尚达人计算:在稳定后,计算与相邻学生颜色不同的学生数量。

感悟

这道题目通过模拟学生校服颜色的变化,考察了对状态变化的模拟和循环检测的能力。通过逐步模拟每一天的状态变化,我们可以有效地判断状态是否稳定,并计算出稳定后的时尚达人数量。这道题目不仅考察了编程能力,还考察了对问题本质的理解和逻辑推理能力。