算法《幸运数字》由2,3, 5, 7 组成的幸运数字

11 篇文章 4 订阅

幸运数字

[题目描述]
    蓝胖是个热爱数学的人,在他心目中每个数位都由2,3, 5, 7 组成的数字是他的幸运数字,而幸运数列是将所有幸运数字排序后得到的递增数列:2,3,5, 7, 22, 23, 25, 27, 32, 33, 35, 37, 52, 53, 55, 57, 72, 73, 75, 77, ..
    蓝胖想知道这个数列中的第n个数字是多少,这个任务现在就交给你了。
[输入]
    本题包含多组数据,输入第一行为一个数Test, 表示数据组数。接下来每组数据包含一个数字n,表示蓝胖的一个一个询问。
[输出]
    输出包含Test 行,每行一个数字,表示该组数据的答案。

[输入样例]
    4
    1
    3
    10
    18
[输出样例]

    7
    2
    5
    33
    73
[数据规模及约定]
    对于30%的数据,n<=2000:
    对于100%的数据,n<=10^10, Test<=2000

# -*- coding: utf-8 -*-
# @Software: PyCharm
# @File : test.py 
# @Author : Benjamin
# @Time : 2021/7/5 15:44

# > 4
# 2
# 3
# 5
# 7 > 字符串长度为1,区长度为1

# > 4*4=16
# 22、23、25、27
# 32、33、35、37
# 52、53、55、57
# 72、73、75、77 > 字符串长度为2,区长度为4

# > 16*4=64
# 222、223、225、227、232、233……
# 322、323、325、327、332、333、335、337……
# 522、523、525、527、532、533、535、537、552、553、555、557、572、573、575、577
# [722、723、725、727]、[732、733、735、737]、[752、753、755、757]、[772、773、775、777] > 字符串长度为3,区长度为16 > 1组4个

# 4 4*4=16 4*4*4=64
# 4+16+64=84

# num = [2, 3, 5, 7]
# 第84位,值为777,长度3位数,求值3次
# strLen、strNum
# 第83位,值为775.长度3位数,求值3次
# 15 一个区域16个值,15分成4个区域,输入第4个区域,故取值7
# 15-4-4-4=3,减去前面3个区域则属于第4个区域,此时得出第二位数字7。3属于该区域的第三个数字由此推断得出第三位数字5
# 15 一个区域16个值,3(15-4*3=3)故取值第3个,故取值为5

# > 64*4=256
# [[2222、2223、2225、2227]、[2232、2233、2235、2237]、[2252…]] > 64 > 2共计64组4个一组
# 3…… > 64
# 5…… > 64
# 7…… > 64

# > 256*4=1024
# [[22222、22223、22225、22227]、[22232……]] > 256
# 4+16+64+256+1024=1364


def getStrInfo(num):
    strLen = 1 # 数字长度
    middle = 0

    begin = 4
    if num <= begin:
        strLen = strLen
        strNum = num
        return strLen, strNum

    while True:
        end = middle + begin
        if begin < num <= end:
            strLen = strLen

            # 正数第几位
            strNum = num - begin
            return strLen, strNum
        begin = end
        strLen += 1
        middle = 4 ** strLen


# 算出首位数字,还有下一次除4取余的的值后的长度和位置
def getlistIndex(strLen,strNum):
    listLen = 4 ** strLen
    # 4^3=64
    one = listLen / 4
    two = one * 2
    three = one * 3
    four = listLen

    strLen = strLen - 1
    if strNum <= one:
        listIndex = 2
        return listIndex, strLen, strNum
    if strNum <= two:
        listIndex = 3
        strNum = strNum - one
        return listIndex, strLen, strNum
    if strNum <= three:
        listIndex = 5
        strNum = strNum - two
        return listIndex, strLen, strNum
    if strNum <= four:
        strNum = strNum - three
        listIndex = 7
        return str(listIndex), strLen, strNum


# 算出所有数据
def listAll(listIndex, strLen, strNum):
    num = [2, 3, 5, 7]
    if strLen == 1:
        index = int(strNum-1)
        return int( str(listIndex) + str(num[index]))

    # 第83位,值为775,长度3位数,求值3次
    # strLen、strNum
    # 15 一个区域16个值,再分成4个区域,属于第4个区域,故取值7
    # 15 一个区域16个值,3(15-4*3=3,取余更快)故取值第3个,故取值为5

    test = "%s"%listIndex
    for i in range(strLen):
        listIndex, strLen, strNum = getlistIndex(strLen,strNum)
        test = test + str(listIndex)
    return test

def getListAll(test):
    ListAllResult = []
    for value in test:
        strLen, strNum = getStrInfo(value)
        listIndex, strLen, strNum = getlistIndex(strLen, strNum)
        getVaule = listAll(listIndex,strLen,strNum)
        ListAllResult.append(getVaule)
    return ListAllResult

if __name__ == "__main__":
    # num = 4
    # strLen, strNum = getStrInfo(num)
    # listIndex, strLen, strNum  = getlistIndex(strLen,strNum)
    # print(listAll(listIndex,strLen,strNum))

    test = [4,1,3,10,18]
    print(getListAll(test))

题解思考

1、4个数字,大小依次分别组合次数相同,共计为4个大组

2、每组数据再分别以4个数字大小依次组合,分别为4个小组

3、依次类推,每4个大组中分成4个小组,可得出每个小组中的第二位数字

4、最后一位取余可得出属于数组中的第几位

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BenjaminQA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值