AtCoder Context ABC 161 D Lunlun Number

运行要求
运行时间限制: 2sec
内存限制: 1024MB
https://atcoder.jp/contests/abc161/tasks/abc161_d

题目
如果一个正整数满足以下条件,那么这个正整数可以被称做Lunlun数

  • Lunlun数用十进制表示的话,任意两个相邻的位数的差的绝对值在1以下

比如,1234,1,334可以叫做Lunlun数, 31415,119,13579不能叫做Lunlun数

给定一个正整数K,求从小到大第K个Lunlun数

输入前提条件

  • 1 <= K <= 100000
  • 所有的输入必须为整数

输入
输入都以以下标准从命令行输入

K

输出
输出答案


例1
输入

15

输出

23

升序排列到第15位的话
1,2,3,4,5,6,7,8,9,10,11,12,21,22,23

第15位是23,所以答案是23


例2
输入

1

输出

1

例3
输入

13

输出

21

例4
输入

100000

输出

3234566667

请注意,32位带符号的整型可能会溢出


读懂题目
它的意思就是说,我们要找到符合条件的自然数当中的整数P。
整个整数P要满足十位数和百位数相差小于等于1,百位数和千位数相差小于等于1......

解题思路

1. 我们很容易想到找到满足条件的1位数,找到满足条件的2位数,找到满足条件的3位数。。。直到找到的数的数量等于K,然后再排序
很容易想到这个图
AtCoder Context ABC 161 D Lunlun Number_第1张图片

2. 满足条件的N位数可以衍生,生成满足条件的N+1位数
我们可以简单地发现规律,觉得可以通过递归的方法遍历到所有的数
但是本人尝试过以后,TLE了。时间上来不及。

3. 递归以外还有一个queue的办法,找到一个数后,把它衍生的数append到queue的后面

4.巧妙的是,这个queue的顺序就是可以按从小到大的顺序排列的

5.产生衍生的数字的方法
给定an,衍生的数字有三个
an*10 + (an % 10 - 1)
an*10 + (an % 10)
an*10 + (an % 10+1)

an % 10 = 0的情况下,产生的衍生有两个
an*10 + (an % 10)
an*10 + (an % 10+1)

an % 10 = 9的情况下,产生的衍生有两个
an*10 + (an % 10)
an*10 + (an % 10-1)

如下面的动图所示
AtCoder Context ABC 161 D Lunlun Number_第2张图片

代码

from collections import deque

K = int(input())

def calculate(n):
    q = deque()
    for i in range(1, 10):
        q.append(i)

    result = []

    while len(result) <= n:
        x = q.popleft()
        result.append(x)
        m = x % 10
        if m == 0:
            q.append(x * 10 + m)
            q.append(x*10+ m +1)
        elif m == 9:
            q.append(x*10 + m - 1)
            q.append(x * 10 + m)
        else:
            q.append(x*10 + m - 1)
            q.append(x * 10 + m)
            q.append(x*10 + m + 1)

    print(result[n-1])


calculate(K)

总结

这道题第一要注意到求衍生的方法
再次注意到用queue的append的话,可以得到升序的队列

※ 另外,我会在我的微信个人订阅号上推出一些文章,欢迎关注
AtCoder Context ABC 161 D Lunlun Number_第3张图片


你可能感兴趣的:(python3.x)