AtCoder ContextABC 136 D Gathering Children(孩子们,来吧)

题目
有一些小格子,这些小格子可以被由字符'L'和'R'构成的字符串S所表示。
字符串S的长度为N,也就是说字符串S由N个小格子从左致右,一列排开。从左往右第i个格子的内容是字符串S的从左往右第i个字符。
最左边的格子的内容必须为'R'
最右边格子的内容必须为'L'
最开始的时候,每个格子里面有一个小孩子。
格子里面的小孩子,按照下面的规则移动10的100次方回。

按照现在所属的格子里的字符的意思移动。比如小孩子所在的格子里写着'L'的话,那么这个孩子就往左移动一个格子。如果小孩子所在的格子里写着'R'的话,那么这个小孩子就往右移动一个格子。那么,这样进行1000次以后,求每个格子里小孩子的人数。

条件

输入
要求以下面的方式输入

S

输出
10的100次方回以后,从左到右各个小格子的人数

例1
输入

RRLRL

输出

0 1 2 1 1

解释

  1. 第1次移动后,从左到右每个小格子的人数是0,2,1,1,1
  2. 第2次移动后,从左到右每个小格子的人数是0,1,2,1,1
  3. 这样移动10的100次方回以后,从左到右每个小格子的人数是0,1,2,1,1

例2
输入

RRLLLLRLRRLL

输出

0 3 3 0 0 0 1 1 0 2 2 0

例2
输入

RRRLLRLLRRRLLLLL

输出

0 0 3 2 0 2 1 0 0 0 4 4 0 0 0 0

解题思路

读懂题目

格子是不移动的
刚开始没有读懂题目,以为是格子里面的字母移动,不是这样的

格子上的人是移动的
格子是固定的,格子里面的字母也是固定的,格子里面的人是要根据格子里面的字母,移动到左边的格子或者移动到右边的格子里面的

basic.jpg

RRRLLL
左边的R最多只能移动到右边的第1个L,如图所示,会被右边的L弹回左边的
如图所示,黑色的点最多移动到哪里?

RRRLLL
右边的L最多只能移动到左边的第3个R,如图所示,会被左边的R弹回右边的
如图所示+点最多移动到哪里?

RRRLLL
所有的点都往中间的RL聚集
如图所示,到了第4步的时候,所有的点都聚集往中间了

basic2.jpg

10的100次方是一个偶数
可以看出,第4步和第6步都是一样的,第5步和第7步都是一样的
10的100次方,也就是说会移动到第4步的样子

奇数项留下,偶数项过去
第4步可以看到留下有两列
左边的一列留下了什么?
右边的一列留下了什么?

代码


# 按照RL的字符聚合,生成数字的数组聚合
# 进入 RRLLLLRLRRLL
# 输出 [[2,4],[1,1],[2,2]]
def calculate(S):
    result = []
 
    rNum = 0
    lNum = 0
    for i in range(len(S)):
        if S[i] == "L":
            lNum = lNum + 1
        else:
            rNum = rNum + 1
 
        if i > 0:
            if (S[i] == "R") and (S[i-1] == "L"):
                result.append([rNum-1,lNum])
                rNum = 1
                lNum = 0
 
        if i == len(S) - 1:
            result.append([rNum,lNum])
 
    return result
 
 
# 方便生成前面的0
# 比如24 --> 0xy000
def constructZero(n):
    res = ""
    for i in range(n):
        res = res + "0 "
    return res

# 这里生成最后的结果
# 比如24 --> 生成0xy000,顺便求出x和y
def calculate2(arr):
    ret = ""
    for index in range(len(arr)):
 
        # 生成前面的0
        s1 = constructZero(arr[index][0]-1)
        s2 = constructZero(arr[index][1]-1)
 
        if arr[index][0] % 2 == 0:
            l1 = arr[index][0]//2 # 算出留下来的,总数是偶数的话留下一半
        else:
            l1 = (arr[index][0] + 1) // 2 # 算出留下来的,总数是奇数的话,留下奇数的,剩下的给对方
 
        g1 = arr[index][0] - l1 # 剩下一半给对方
 
        if arr[index][1] % 2 == 0:
            l2 = arr[index][1]//2 # 算出留下来的,总数是偶数的话留下一半
        else:
            l2 = (arr[index][1] + 1) // 2 // 2 # 算出留下来的,总数是奇数的话,留下奇数的,剩下的给对方
 
        g2 = arr[index][1] - l2 # 剩下一半给对方
 
        # 拼接结果
        ret = ret + s1 + str(l1 + g2) + " " + str(l2 + g1)+ " " + s2
 
    return ret
 
S = input()
result = calculate(S)
ret = calculate2(result)
print(ret)

你可能感兴趣的:(python,python3.x,算法复杂度)