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

167 阅读5分钟

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

多米诺骨牌均衡状态 - MarsCode

摘要

本文解决了多米诺骨牌均衡状态的问题,给定一个多米诺骨牌的初始状态,模拟骨牌倒下的过程,确定哪些骨牌保持竖立。通过两个辅助数组记录左右推倒骨牌的受力时间,并结合该信息最终输出竖立骨牌的位置。我们提供了详细的解题思路与代码实现。

问题描述

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

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

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

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

示例

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

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

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

解题步骤

1. 初始化状态

使用一个数组 finalState 来记录每个骨牌的最终状态:

  • 0 表示骨牌保持竖立。
  • 正整数表示骨牌被向右推倒。
  • 负整数表示骨牌被向左推倒。

此外,使用两个辅助数组 timeRtimeL 分别记录每个骨牌被右推('R')和左推('L')时的影响时间。这两个数组有助于确定哪些骨牌处于平衡状态。

2. 处理右倒('R')的骨牌

从左到右遍历字符串,遇到 'R' 时:

  • 标记当前骨牌为受力状态。
  • 从当前骨牌的右侧开始,标记所有竖立的骨牌为向右倒,并记录右推的受力时间。

3. 处理左倒('L')的骨牌

从右到左遍历字符串,遇到 'L' 时:

  • 标记当前骨牌为受力状态。
  • 从当前骨牌的左侧开始,标记所有竖立的骨牌为向左倒,并记录左推的受力时间。

4. 确定竖立的骨牌

最终,遍历所有骨牌的位置,检查哪些位置的骨牌受力平衡(即 finalState[i] == 0),并且其左右倒力的受力时间一致(timeR[i] == timeL[i])。这些骨牌即为竖立的骨牌。

5. 输出结果

如果有竖立的骨牌,返回这些骨牌的位置(1-based index),并按从大到小的顺序输出。如果没有竖立的骨牌,返回 "0"。

代码实现

Go语言代码

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func solution(num int, data string) string {
	// finalState 数组记录每个骨牌的最终状态,0 代表竖立,负数代表向左倒,正数代表向右倒
	finalState := make([]int, num)

	// 先处理右倒(R)
    timeR:=make([]int,num)//记录向右倒时的受力时间
	for i := 0; i < num; i++ {
		if data[i] == 'R' {
			finalState[i] = 2 //初始骨牌不纳入计算
			// 向右倒的骨牌会影响之后的骨牌
            cnt:=1
			for j := i + 1; j < num && data[j] == '.'; j++ {
				finalState[j] = 1
                timeR[j]=cnt
                cnt++
			}
		}
	}

	// 然后处理左倒(L)
    timeL:=make([]int,num)//记录向左倒时的受力时间
	for i := num - 1; i >= 0; i-- {
		if data[i] == 'L' {
			finalState[i] = 2 // 
			// 向左倒的骨牌会影响之前的骨牌
            cnt:=1
			for j := i - 1; j >= 0 && data[j] == '.'; j-- {
				finalState[j]--
                timeL[j]=cnt
                cnt++
			}
		}
	}

	// 找出竖立的骨牌,并存入结果
	var result []int
	for i := 0; i < num; i++ {
		if finalState[i] == 0&&timeL[i]==timeR[i] {
			result = append(result, i+1) // 1-based index
		}
	}

	// 如果没有竖立的骨牌
	if len(result) == 0 {
		return "0"
	}

	// 格式化输出
	var builder strings.Builder
	builder.WriteString(strconv.Itoa(len(result)))
	builder.WriteString(":")
	for i := 0; i < len(result)-1; i++ {
		builder.WriteString(strconv.Itoa(result[i]))
		builder.WriteString(",")
	}
	builder.WriteString(strconv.Itoa(result[len(result)-1]))

	return builder.String()
}

func main() {
    // 你可以添加更多的测试用例
    fmt.Println(solution(14, ".L.R...LR..L..") == "4:3,6,13,14")
    fmt.Println(solution(5, "R....") == "0")
    fmt.Println(solution(1, ".") == "1:1")
}

Python代码

def solution(num, data):
    """
    该函数接受一个整数 num 和一个字符串 data,表示骨牌的数量和初始状态。
    返回保持竖立状态的骨牌位置列表(1-based index),格式为 "<数量>:<位置1>,<位置2>,...<位置N>"。
    如果没有骨牌保持竖立,返回 "0"。
    """
    # 初始化 finalState 数组,0 表示竖立,-1 表示向左倒,1 表示向右倒
    final_state = [0] * num

    # 初始化时间数组,用于记录向左倒和向右倒的受力时间
    time_r = [0] * num  # 向右倒的时间记录
    time_l = [0] * num  # 向左倒的时间记录

    # 处理右倒('R')的影响
    for i in range(num):
        if data[i] == 'R':
            final_state[i] = 2  # 表示该位置是初始向右倒的骨牌
            cnt = 1  # 初始化受力时间
            for j in range(i + 1, num):
                if data[j] == '.':
                    final_state[j] = 1  # 向右倒的影响
                    time_r[j] = cnt  # 记录向右倒的受力时间
                    cnt += 1
                else:
                    break  # 遇到其他骨牌终止影响

    # 处理左倒('L')的影响
    for i in range(num - 1, -1, -1):
        if data[i] == 'L':
            final_state[i] = 2  # 表示该位置是初始向左倒的骨牌
            cnt = 1  # 初始化受力时间
            for j in range(i - 1, -1, -1):
                if data[j] == '.':
                    final_state[j] -= 1  # 向左倒的影响
                    time_l[j] = cnt  # 记录向左倒的受力时间
                    cnt += 1
                else:
                    break  # 遇到其他骨牌终止影响

    # 找出保持竖立的骨牌
    result = []
    for i in range(num):
        if final_state[i] == 0 and time_l[i] == time_r[i]:  # 确保向左和向右的受力时间相等
            result.append(i + 1)  # 1-based index

    # 如果没有竖立的骨牌,返回 "0"
    if len(result) == 0:
        return "0"

    # 格式化输出
    result_str = f"{len(result)}:" + ",".join(map(str, result))
    return result_str


if __name__ == "__main__":
    # 测试用例
    print(solution(14, ".L.R...LR..L..")

 == "4:3,6,13,14")  # 应输出 True
    print(solution(5, "R....") == "0")  # 应输出 True
    print(solution(1, ".") == "1:1")  # 应输出 True