练习题/ 幸运字符串 对此问题的所有提交都是公开的。查看所有提交内容。
幸运数字是那些仅包含“4”和/或“5”的数字。例如,4,5,44,54,55,444是幸运数字,而457,987,154则不是。
幸运数字序列是所有幸运数字按递增顺序存在的顺序,例如4,5,44,45,54,55,444,445,454,455 ...
现在我们将所有幸运数字(按升序排列)连接成一个幸运字符串“4544455455444445454455 ...”
给定n,您的任务是找到幸运字符串的第n个数字。如果数字是4,那么你必须打印“黑客”,否则你必须打印“地球”。
第一行包含多个测试用例T
,下一个T
行包含一个整数n
。
对于每个测试用例,如果幸运字符串的第n位为Hacker
,则打印4
如果幸运字符串的第n位为Earth
,则打印5
。< / p>
1 <= t <= 10^5
1 <= n <= 10^15
test_cases = int(input())
final = []
def check(stra,num):
if stra[num-1]==4:
final.append("Hacker")
else:
final.append("Earth")
def GenStr(num):
stra = "4"
i = int(5)
while(len(stra)<num+2):
X = str(i)
flag = True
for j in range(len(str(i))):
if(X[j]==4 or X[j]==5):
pass
else:
flag = False
if flag==True:
stra+=X
i+=1
print(stra)
return stra
for i in range(test_cases):
num = int(input())
# generate string
stra = GenStr(num)
print("stra "+stra)
# check the stat
check(stra,num)
print("\n".join(final))
这段代码出了什么问题,请不要介意这是一个愚蠢的错误我只是python编程的初学者
答案 0 :(得分:1)
以下是不正确的事情。 stra
为4. flag
始终为False
。因此stra
永远不会增长,while(len(stra)<num+2):
是无限循环。
这种方法本身并不能完全解决问题,因为你不能构造一个长度为10 15 的字符串,这需要花费太多时间而且只是赢了。适合记忆。
答案 1 :(得分:1)
您的代码中有几件事情没有多大意义,需要解决:
int(input())
说要求用户没有,尝试转换他们键入的任何字符串,然后按Enter键输入整数,否则崩溃。for i in range(len(x))
在Python中几乎总是错误的。字符串是可迭代的(它们是字符列表),这就是为什么你可以使用列表样式的索引操作符(就像你使用x[j]
),所以只需迭代它们:for j in str(i)
。if x==True:
始终错误。我们更喜欢if x:
。i = int(5)
。无需将整数文字转换为整数。 i = 5
是正确的赋值语句。stra
(字符串a ??),X
,num
等。我会诚实地说:我并不完全理解所提出的任务。目前尚不清楚什么是“测试用例”或输入将如何格式化(或者,就此而言,输入来自何处)。也就是说,关于如何处理这个问题的一些想法:
len(str(x).replace('4', '').replace('5', ''))
一样简单,并且有更好的方法。sorted
函数完成按递增顺序列出“幸运数字”。''.join(sorted(lucky_numbers))
或类似。答案 2 :(得分:0)
正如@Gassa所指出的那样,暴力迫害这只是行不通;你需要一百万GB的RAM,这需要太长时间。
那么分析解决方案会是什么样子?
如果将“4”替换为“0”而将“5”替换为“1”,您将看到幸运数字序列变为0, 1, 00, 01, 10, 11, 000, 001, 010, 011, 100, 101, 110, 111, ...
。这应该看起来很熟悉:它是按升序排列的每1位二进制数,后面是按升序排列的每2位二进制数,后跟每个3位二进制数,按升序排列等。
所以,如果你做了像
这样的事情n = 491 # the digit we are seeking (for example)
d = 1 # number of binary digits
p = 2 # 2**d == number of items encoded
while n > d*p: # sought digit is past the end of the next binary expansion?
n -= d*p # reduce offset by appropriate number of digits
d += 1
p *= 2
然后n = 233, d = 6
意味着我们正在寻找6位扩展中的第233个字符。
但我们可以改进:
k, n = n // d, n % d
给出n = 5, k = 38, d = 6
意味着我们正在查看第38个6位值的第5个字符。
注意:此处的所有偏移均为0;如果您希望基于1的偏移,则必须相应地调整数学运算!
第38个6位值仅38转换为6位二进制值;你可以用字符串来解压缩你想要的字符,但是可能更容易记住整数在内部存储为二进制,所以我们可以通过一些数学得到我们想要的东西:
digit = (k >> (d - n - 1)) & 1 # => 0
因此原始字符串中的字符将为“4”。