多米诺骨牌均衡问题| 豆包MarsCode AI刷题

58 阅读4分钟

问题描述

小S玩起了多米诺骨牌,他排列了一行骨牌,并可能将某些骨牌向左或向右推倒。随着骨牌连锁反应的进行,一些骨牌可能因为左右两侧受力平衡而保持竖立。现在小S想要知道在所有动作完成后,哪些骨牌保持竖立。

给定一个表示骨牌初始状态的字符串,其中:

  • "L" 表示该位置的骨牌将向左倒。
  • "R" 表示该位置的骨牌将向右倒。
  • "." 表示该位置的骨牌初始时保持竖立。

模拟整个骨牌倒下的过程,求出最终仍然保持竖立的骨牌的数目和位置。


测试样例

样例1:

输入:num = 14,data = ".L.R...LR..L.."
输出:'4:3,6,13,14'

样例2:

输入:num = 5,data = "R...."
输出:'0'

样例3:

输入:num = 1,data = "."
输出:'1:1'

这个问题可以通过模拟多米诺骨牌的倒下过程来解决。我们需要考虑两个主要因素:

  1. 左推与右推的影响L 表示向左推倒,R 表示向右推倒。它们会影响周围的骨牌,直到没有更多的骨牌受到影响。
  2. 左右受力平衡:如果一个骨牌同时受到来自左侧和右侧的推力,我们需要根据两侧的力量平衡来决定它是否倒下。如果某个骨牌只受到单边的推力(如右侧或左侧),它会倒向那一侧。如果两侧的推力在时间上是平衡的,它会保持竖立。

解题思路:

  1. 模拟骨牌倒下的过程:遍历整个字符串,通过两个方向的推力传播更新每个骨牌的状态。使用两个数组来记录从左向右推的影响和从右向左推的影响。
  2. 保持竖立的骨牌:对于每个骨牌,如果它既没有被右侧推倒,也没有被左侧推倒,它就保持竖立。

步骤:

  1. 从左到右遍历,计算从左侧推到当前骨牌的影响。
  2. 从右到左遍历,计算从右侧推到当前骨牌的影响。
  3. 检查每个骨牌是否保持竖立。如果骨牌既没有被左侧影响,也没有被右侧影响,则它保持竖立。

代码实现:

def solution(num, data):
    # 初始化两个数组来表示左右方向的影响时间
    left_force = [-1] * num  # -1表示没有被影响,其他值表示倒下的时间
    right_force = [-1] * num  # 同上

    # 从左到右遍历,记录每个骨牌被右侧推倒的影响
    time = -1  # 用来记录右侧影响的时间
    for i in range(num):
        if data[i] == 'R':
            time = 0
        elif data[i] == 'L':
            time = -1
        if time >= 0:
            right_force[i] = time
            time += 1  # 影响时间逐渐递增
    
    # 从右到左遍历,记录每个骨牌被左侧推倒的影响
    time = -1  # 用来记录左侧影响的时间
    for i in range(num-1, -1, -1):
        if data[i] == 'L':
            time = 0
        elif data[i] == 'R':
            time = -1
        if time >= 0:
            left_force[i] = time
            time += 1  # 影响时间逐渐递增

    # 判断哪些骨牌保持竖立
    standing = []
    for i in range(num):
        if data[i] == '.' and right_force[i] == -1 and left_force[i] == -1:
            standing.append(i + 1)  # 记录竖立的骨牌位置,注意要加1
    
    # 如果没有竖立的骨牌,返回0
    if not standing:
        return "0"
    
    # 返回竖立骨牌的数量和位置
    return f"{len(standing)}:{','.join(map(str, standing))}"

# 测试代码
if __name__ == "__main__":
    print(solution(14, ".L.R...LR..L..") == "4:3,6,13,14")
    print(solution(5, "R....") == "0")
    print(solution(1, ".") == "1:1")

解释:

  1. 数组 left_forceright_force

    • right_force[i] 表示从左到右传播的推力影响,如果骨牌 i 受到右推影响,则 right_force[i] 存储推力的时间,时间值递增。
    • left_force[i] 表示从右到左传播的推力影响,处理方式类似。
  2. 两次遍历

    • 第一次从左到右遍历,记录右侧推力的影响。
    • 第二次从右到左遍历,记录左侧推力的影响。
  3. 判断竖立的骨牌

    • 对于每个位置 i,如果 data[i].(竖立的骨牌),并且 right_force[i]left_force[i] 都没有受到影响(即值为 -1),则说明该骨牌保持竖立。
  4. 返回结果

    • 如果有竖立的骨牌,返回它们的数量和位置;如果没有,则返回 0