颠倒的数字定义为:
颠倒的数字是i的整数 左边的数字加上i 右边的数字是 总是等于10.例如13579是一个颠倒的数字,因为1 + 9 = 10,3 + 7 = 10和(从那以后) 5是左起第三位和右起5 + 5 = 10。 按数字顺序排列的前几个倒数字是5,19,28,37,......,82,91,159 ......
任务
编写程序以确定第n个倒置数字(按数字顺序)。
输入将由单个整数n(1 我的代码 对于小于100的数字,代码是正常的,但是对于与'1234'一样大的数字,它需要在两秒内运行,这应该产生'4995116'的答案。 它确实有效但只需要太长时间(通常约30秒)。它需要在2秒内完成;( 提前感谢您的帮助。 注意:这不是考试/家庭作业等,只是为了帮助我准备考试def upsidecheck(tocheck):
intolist=list(map(int, str(tocheck)))
x=0
while x<(len(intolist)/2):
if (intolist[x]+intolist[len(intolist)-x-1])!= 10 :
return False
break
x+=1
return True
print("which nth upsidedownnumber do you want?")
nth=int(input())
y=0
answer=0
for x in range (1,(2**31)):
counter=upsidecheck(x)
if counter == True:y+=1
if y==nth:answer=x;break
print("the answeris",answer)
答案 0 :(得分:1)
首先,我们需要一个函数来告诉我们哪些数字是颠倒的:
def is_ud(n):
digits = [int(ch) for ch in str(n)]
check = (len(digits) + 1) // 2
return all(digits[i] + digits[-1 - i] == 10 for i in range(check))
然后让我们生成一些值并寻找模式:
ud = [i for i in range(10000000) if is_ud(i)]
for digits in range(1, 8):
lo, hi = 10 ** (digits - 1), (10 ** digits) - 1
answers = sum(lo <= n <= hi for n in ud)
print("{}: {}".format(digits, answers))
给出了
1: 1
2: 9
3: 9
4: 81
5: 81
6: 729
7: 729
因此有81个4位数解决方案和729个6位数解决方案;这应该是有道理的,因为6位数的解决方案看起来像&#34; 1&#34; +(每个4位数解决方案)+&#34; 9&#34;,&#34; 2&#34; +(每个4位数解决方案)+&#34; 8&#34;,...&#34; 9&#34; +(每个4位数解决方案)+&#34; 1&#34; - 因此,每4位数解决方案有9个6位数解决方案(如果以这种方式生成它们,您将按升序生成它们)。同样,对于每个4位数的解决方案,通过在中间插入5来解决相应的5位数解决方案。
查看此表,您现在应该可以看到,如果您想要(例如)第200个解决方案,它必须有6位数字;事实上,它必须是第19个6位数的解决方案。不止于此,因为19&lt; 81,它必须看起来像&#34; 1&#34; +第19个4位数解决方案+&#34; 9&#34;!
您现在拥有编写递归解决方案以直接生成第N个倒置数字所需的一切。祝你好运!
答案 1 :(得分:0)
由于这里的所有数字强制执行不是一个选项,因此您需要先解决数学问题:
对于第一个,“倒置”数字是:
由于相同长度的数字是逐位比较的,因此猜测哪个顺序是升序。
第二,
答案 2 :(得分:0)
这是一个有趣的问题。正如其他人所说,第一部分是你想要任意数量的数字的第n个数字,所以如果你能找到数字较少的数字的总数,你可以从数值中减去它们并忽略它们。
然后你有一个更简单的问题:找到恰好有k位数的第n个值。如果k是奇数,则中心数字是&#39; 5&#39;,否则前半部分只是第n个基数9,但是数字表示在1..9的范围内。尾部只是相同的基数9值,数字反转,使用范围9..1表示值0..8。
此函数会将值转换为基数9,但具有用于表示每个数字的特定字符:
def base9(n, size, digits):
result = []
for i in range(size):
result.append(n%9)
n //= 9
return ''.join(digits[i] for i in reversed(result))
例如:
>>> print(base9(20, 3, "abcdefghi"))
acc
现在要打印第n个倒置号码,我们将k
个数字准确转换为基数9并插入&#39; 5&#39;如果需要的话。
def ud_fixed(n, k):
"""Upside down number of exactly k digits
0 => 1..159..9
1 => 1..258..9
and so on
"""
ln = k // 2
left = base9(n, ln, "123456789")
right = base9(n, ln, "987654321")[::-1]
if k%2:
return left + "5" + right
else:
return left + right
现在我们需要做的就是计算有多少更短的结果并忽略它们:
def upside_down(n):
number = [1, 9]
total = [1, 10]
if n==1: return "5"
while total[-1] < n:
number.append(9*number[-2])
total.append(total[-1]+number[-1])
length = len(total)
if length >= 2:
n -= total[length-2] # Ignore all the shorter results.
return ud_fixed(n-1, length)
打印一些值以进行检查:
if __name__=='__main__':
for i in range(1, 21):
print(i, upside_down(i))
print(1234, upside_down(1234))
输出如下:
C:\Temp>u2d.py
1 5
2 19
3 28
4 37
5 46
6 55
7 64
8 73
9 82
10 91
11 159
12 258
13 357
14 456
15 555
16 654
17 753
18 852
19 951
20 1199
1234 4995116
答案 3 :(得分:0)
代码位于一个模块中,OP可以从中导入ud
函数。
% cat upside.py
# module variables
# a table with the values of n for which we have the greatest
# UD number of i digits
_t = [0, 1]
for i in range(1,11): last = _t[-1] ; d=9**i ; _t+=[last+d,last+d+d]
# a string with valid digits in our base 9 conversion
_d = '123456789'
def _b9(n,l):
# base 9 conversion using the numbers from 1 to 9
# note that we need a zero padding
s9 = []
while n : s9.append(_d[n%9]) ; n = n//9
while len(s9)<l: s9.append(_d[0]) # ZERO PADDING!
s9.reverse()
return ''.join(s9)
def _r9(s):
# reverse the first half of our UD number
return ''.join(str(10-int(c)) for c in s[::-1])
def ud(n):
# Error conditions
if n<1:raise ValueError, 'U-D numbers count starts from 1, current index is %d.'%(n,)
if n>_t[-1]:raise ValueError, 'n=%d is too large, current max is %d.'%(n,_t[-1])
# find length of the UD number searching in table _t
for i, j in enumerate(_t):
if n<=j: break
# the sequence number of n in all the OD numbers of length i
# note that to apply base9 conversion we have to count from 0,
# hence the final -1
dn = n-_t[i-1]-1
# now we compute the "shifted base 9" representation of the ordinal dn,
# taking into account the possible need for padding to a length of i//2
a = _b9(dn,i//2)
# we compute the string representing the OD number by using _r9 for
# the second part of the number and adding a '5' iff i is odd,
# we convert to int, done
return int(a+('5' if i%2 else '')+_r9(a))
%
这是一个使用示例
% python
Python 2.7.8 (default, Oct 18 2014, 12:50:18)
[GCC 4.9.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from upside import ud
>>> ud(1234)
4995116
>>> ud(7845264901)
999999999951111111111L
>>> ud(7845264902)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "upside.py", line 15, in ud
if n>_t[-1]:raise ValueError, 'n=%d is too large, current max is %d.'%(n,_t[-1])
ValueError: n=7845264902 is too large, current max is 7845264901.
>>> exit()
%
除了评论和错误处理之外,ud(n)
非常短......
def ud(n):
for i, j in enumerate(_t):
if n<=j: break
dn = n-_t[i-1]-1
a = _b9(dn,i//2)
return int(a+('5' if i%2 else '')+_r9(a))