1084 外观数列 (20 分)

1084 外观数列 (20 分)

题意描述:

外观数列是指具有以下特点的整数序列:

d, d1, d111, d113, d11231, d112213111, ...

它从不等于 1 的数字 d 开始,序列的第 n+1 项是对第 n 项的描述。比如第 2 项表示第 1 项有 1 个 d,所以就是 d1;第 2 项是 1 个 d(对应 d1)和 1 个 1(对应 11),所以第 3 项就是 d111。又比如第 4 项是 d113,其描述就是 1 个 d,2 个 1,1 个 3,所以下一项就是 d11231。当然这个定义对 d = 1 也成立。本题要求你推算任意给定数字 d 的外观数列的第 N 项。

输入格式:
输入第一行给出 [0,9] 范围内的一个整数 d、以及一个正整数 N(≤ 40),用空格分隔。

输出格式:
在一行中给出数字 d 的外观数列的第 N 项。

输入样例:

1 8

输出样例:

1123123111

解题思路:
Mara: 复杂,o((⊙﹏⊙))o
Jack:再复杂也是简单的叠加,拆开来看呗。外观描述,就是好像那个啥压缩算法一样,好像是行程压缩编码,就是这个样子。将连续的数字用数字和计数来编码。比如说“1111000” =》“1403”。
Mara: 让我推一推,像题目里面描述的如果d是1的话,那应该是:

1
11
12
1121
122111
112213
12221131
1123123111

还真是这样的,统计连续出现的相同数字的个数。hiahiahia
Jack: 然后这道题还有一个迭代的过程,用循环写就好了。
Mara: 那是不是还能用递归写啊,怎么不用递归啊,递归不是好写吗?
Jack: 我不太会写递归的,(✿◡‿◡),就用循环吧。然后 N 是 1 的话特殊处理一下, N不是 1 的时候,从第一项 变到 第N项, 一共需要 N - 1步。
Mara: ♪ d(^^*) 循环比递归跑的快呀,就用循环吧。
Jack: 好(^ o ^)/~


代码:

def main():
    d, N = (int(x) for x in input().split())
    # 接收整数d,范围是[0,9]以及一个正整数 N(≤ 40)。
    previous = str(d)
    # 将数字d变成字符串形式,便于后续处理。
    if N > 1:
        # 如果求得是 外观数列的 第2项或者任何后边的项。
        for x in range(N - 1):
            # 第一项与第N项之间的间隔是N-1,即只需要迭代N-1次。
            result = out_look(previous)
            # 迭代一次, result就是对previous的外观描述。
            previous = result
            # 将一次迭代的结果再次进行迭代。
    else:
        # 如果求得是外观数列的第一项,其实就是整数d自身。
        result = previous
    print(result)
    # 输出答案


def out_look(previous):
    """
       返回对previous的外观描述,输入为字符串,输出为字符串。
    """
    element = previous[0]
    # 取出previous 的第一项作为起始元素
    index = 0
    count = 1
    # index 指示当前位置, count 指示截止到当前位置element 元素共有多少。
    answer = ""
    # answer存储最终的 外观描述
    while True:
        # 我们在内部做判断,然后break出去。为什么这样做呢?因为在循环的内部我们
        # 需要试探着向后寻找同element相等的元素,而试探首先要保证不会造成数组
        # 越界。当然,这点可能不是一下子就能想到的。也就是说将判断放在循环内部是
        # 优化后的程序结构。
        index += 1
        # 试探着向后看
        if index < len(previous):
            # 没有越界,可以看
            if previous[index] == element:
                count += 1
                # element元素在重复,count记下数就可以了
            else:
                # 新的element已经出现,将旧的element和出现的次数记好
                answer += "{}{}".format(element, count)
                element = previous[index]
                count = 1
                # 新的element和新的count
        else:
            answer += "{}{}".format(element, count)
            # 不能再向后了,后面已经没有元素了。记录一下最后一个index和count
            break
            # 然后终止循环
    return answer
    # 返回答案


if __name__ == '__main__':
    main()


易错点:

  • N == 1 的时候,输出d自身。
  • d, d1, d111, d113, d11231, d112213111, ... 可以作为d != 1 时,前六项的公式。但是求公式再代入是不必要的,公式的存储(最多到第40项)是要占内存的哦,还不如直接求,又快又省。

总结:

  • 行程长度编码
  • format( )
Summer Breeze
1084 外观数列 (20 分)_第1张图片

你可能感兴趣的:(#,PAT游乐园,PAT,Python)