两种解法(35行/13行,复杂度都是O(n)):

python35行O(n):

  1. 统一向左和向右倒下
  2. 叠加两个数组判断最终状态
def build_seq(s, flag='R', stop='L', start=0, end=-1, step=1):
    # flag 开始倒的标志
    ts, beg_collapse = s.copy(), False
    for i in range(start, end, step):
        if beg_collapse:
            if ts[i] == stop:
                beg_collapse = False
            else:
                ts[i] = flag
        elif ts[i] == flag:
            beg_collapse = True
    return ts

s = [i for i in input()] # for python 3
l2r = build_seq(s, 'R', 'L', 0, len(s), 1) # 先全部安排向右倒
r2l = build_seq(s, 'L', 'R', len(s)-1, -1, -1) # 再全部安排向左倒

res, i = [ord(i)-ord(j) for i, j in zip(l2r, r2l)], 0
while i < len(s):
    cal = abs(res[i])
    if cal == 0: # '.'-'.' or 'R'-'R' or 'L'-'L'
        res[i] = l2r[i]
    elif cal == 36: # abs('R'-'.')=36
        res[i] = 'R'
    elif cal == 30: # abs('L'-'.')=30
        res[i] = 'L'
    elif cal == 6: # abs('R'-'L')=6
        start = i
        while abs(res[i]) == 6: 
            i += 1
        half = (i-start)//2
        res[start+half] = '.' # 中间不倒
        res[start: start+half] = ['R'] * half # 左边一半右倒
        res[i-half: i] = ['L'] * half # 右边一半左倒
        i -= 1
    i += 1

print(''.join(res))

更巧的解法是投影法:复杂度O(n)

  1. 依旧是双方向扫两次数组;
  2. 从左往右扫描时考虑向右倒下的方块的影子,每过一格影子长度减1,遇到'R'重置影长、遇到'L'清空影长、遇到'.'投影非负影长;同理,右往左扫描时考虑左倒方块的影子;
  3. 对两个方向的影子数组求差 —— 以下文代码为例,右倒数列减去左倒数列,则差大于0是'R',小于0为'L',等于0为'.'。
def func(s, length, flag='R', stop='L'):
    shadow, ts = 0, [0] * length
    for i in range(length):
        shadow = 0 if s[i] == stop else (length if s[i] == flag else max(shadow-1, 0))
        ts[i] = shadow
    return ts

s = [i for i in raw_input()] # for python 2.7
l = len(s)
l2r, r2l = func(s, l, 'R', 'L'), func(s[::-1], l, 'L', 'R')[::-1]

for i in range(l):
    cal = l2r[i] - r2l[i]
    s[i] = '.' if cal == 0 else ('L' if cal < 0 else 'R')

print(''.join(s))