[算法]无限递归字符串查询(python实现)

天大地大妈咪最大 提交于 2019-12-08 09:17:01

无限递归字符串查询

题目地址:the-infinite-string

题目描述

Description

Consider a string A = “12345”. An infinite string s is built by performing infinite steps on A recursively. In i-th step, A is concatenated with ‘$’ i times followed by reverse of A. A=A|$…$|reverse(A), where | denotes concatenation.

Constraints:1<=Q<=10^5, 1<=POS<=10^12

Input

输入第一行为查询次数,后面为每次查询的具体字符位置。

Output

输出每一次查询位置上的字符。

Sample Input 1

2
3
10

Sample Output 1

3
2
题目解析:
题目中的A=A|$...$|reverse(A)是什么意思呢,如下所示
A1 = 12345 
A2 = 12345$54321  = A1|$*1|reverse(A1)
A3 = 12345$54321$$12345$54321   = A2|$*2|reverse(A2) =  A2|$*2|A2
...
An = An-1|$*n-1|reverse(An-1) = An-1|$*n-1|An-1
思路解析:
  1. 除A1外,所有字符串都是对称的,即A = reverse(A),所以初始状态从A2也就是12345$54321 开始,所有的字符串都满足规律An = An-1|$*n-1|An-1
  2. 根据查询的位置q构造字符串Ai ,直到len(Ai-1 )< q <=len(Ai)为止,此时第Ai个字符串的长度一定大于查询的位置q,第Ai-1个字符串的长度一定小于q,意味着这个字符串是刚刚够查询的.并保存此时的$符的数量与字符串长度
  3. 查询位置q(len(Ai-1 )< q <=len(Ai))一定满足如下几种情况
    1. 若 len(Ai-1 )<q<=len(Ai-1 )+len($),说明q所在的位置是$
    2. 若 len(Ai-1 )+len($)<q,观察An的结构(An = An-1|$*n-1|An-1),说明q所在的位置是在An-1中,此时去An-1中寻找,将查询位置q更新为q = q-len(Ai-1 )+len($),
    3. 重复以上过程,直到q<len(A2)为止(此时可以直接用A2[q-1]来获得字符)
代码
# q 所求的第q个位置
# 返回 第q个位置所在的字符串
def GetValues(q):
    size = 5  # 计算字符串的数量 初始为5
    itr = 0
    while True:
        if q <= size:
            return size, itr  # 返回值   字符串长度, $符号的数量
        itr += 1  # 计算$符的数量  ,每次$符号的数量+1
        size = (size * 2) + itr  # 第一次为11 12345$54321   每次新字符串的长度等于两倍的原来字符串的长度加上$符号的个数


def GetChar(q):
    g_str = ['1', '2', '3', '4', '5', '$', '5', '4', '3', '2', '1']
    while q > len(g_str):
        # 构造出一个位置上包含q的串,  如果 A<=q 则停止构造
        m, itr = GetValues(q)  # q 一定大于等于A的长度 (m - itr) / 2)
        # 因为字符串的形式是A|$*n|reverse(A)
        # 这里我们首先求出A|$*n|的长度 , 用总长度-$_长度再除以2再加上|$*n|
        val = int(((m - itr) / 2) + itr)  # 若   A=<q<=A+n 则是$符号
        if q <= val:  # 若所求长度比A长度小
            q = 6
            break
        q -= val  # 若所求长度比A长度大,则所求的字符位置在reverse(A)中  #若 A+n<q 说明在上一个A串中
    if q > 0:
        return g_str[q - 1]
    return ""


if __name__ == '__main__':
    case_num = [int(x) for x in input().strip().split(" ")][0]
    for i in range(case_num):
        x = int(input().strip())
        print(GetChar(x ))

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!