问题描述
多米诺骨牌游戏规则非常简单,将骨牌按一定间距的尺寸排成单行,或分行排成一片。推倒第一张骨牌,其余发生连锁反应依次倒下,或形成一条长龙,或形成一幅图案。
小 A 觉得多米诺骨牌超级没意思,所以他想了点小花招。
小 A 将 n 个多米诺骨牌放在一条线上,每一块都垂直竖立。他同时将一些骨牌向左或向右推倒。注意:不会出现连续向左或者向右推的情况。 每过一秒,被推向左边或右边的骨牌会将左边或右边的相邻骨牌推倒。当一个骨牌,其左边倒向它的骨牌数目与其右边倒向它的骨牌数目相等时,由于力的平衡,该骨牌将依然保持竖立。
给定小 A 最初推骨牌的方向,求出最后依然保持竖立的骨牌数目和位置。
输入格式
输入数据第一行包括一个整数 n(1≤n≤3000),表示这一行多米诺骨牌的数目。下一行包括一个长度为 n 的字符串,字符串的第 i 个字符意义如下:
“L”,第 i 个字符将要被向左推。
“R”,第 i 个字符将要被向右推。
“.”,第 i 个字符不会被推。
输出格式
首先输出保持竖立的骨牌数目。如果保持竖立的骨牌数目不为 0,下一行输出保持竖立的骨牌的位置,骨牌位置从 1 到 n。
每两个数之间用一个空格隔开,注意最后一个数后面没有空格。
输入样例
14
.L.R...LR..L..
5
R....
1
.
输出样例
4
3 6 13 14
0
1
1
golang实现如下:
package main
import (
"fmt"
"strconv"
"strings"
)
func solution(n int, data string) string {
// 初始化左右力数组
leftForce := make([]int, n)
rightForce := make([]int, n)
// 计算右向力
force := 0
for i := 0; i < n; i++ {
if data[i] == 'R' {
force += 1
} else if data[i] == 'L' {
force = 0
} else {
if i == 0 {
force = max(0, force-1)
} else if data[i-1] == '.' && force > 0 {
force += 1
}
}
rightForce[i] = force
}
// 计算左向力
force = 0
for i := n - 1; i >= 0; i-- {
if data[i] == 'L' {
force += 1
} else if data[i] == 'R' {
force = 0
} else {
if i == n-1 {
force = max(0, force-1)
} else if data[i+1] == '.' && force > 0 {
force += 1
}
}
leftForce[i] = force
}
// 确定最终状态
var standingIndices []int
for i := 0; i < n; i++ {
if leftForce[i] == rightForce[i] {
standingIndices = append(standingIndices, i+1)
}
}
//fmt.Println("leftForce=", leftForce)
//fmt.Println("rightForce=", rightForce)
//fmt.Println("standingIndices=", standingIndices)
// 构建输出结果
standNum := len(standingIndices)
retstr := strconv.Itoa(standNum)
if standNum > 0 {
retstr += ":"
retstr += strings.Trim(strings.Join(strings.Fields(fmt.Sprint(standingIndices)), " "), "[]")
}
return retstr
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
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
/**
运行结果:
4:3 6 13 14
0
1:1
*/
}