(删除的44仍然是44。)感谢Fireflame241节省了一个字节!
P=input();i=P/3
while i*10%P-1:i-=1
print i
在线尝试!
之间恰好有一个数字,0
并且P-1
是的倒数10
。但是,如果该逆u
恰好大于P/2
,则(u-P)
它也是一个逆,并且绝对值小于u
。事实证明,我们实际上是x
在-P/2
和之间寻找唯一数字,P/2
这是10
。
上面的代码正是这样做的,从(的底部)开始P/2
,然后逐步向下直到达到逆。-P/2
只要P
大于的素数,就必须发生大于的数10
。更确切地说,它将仅在以下情况下终止P
与互素时10
。
编辑:实际上,事实证明x
保证在-P/3
和之间P/3
,因此当前版本P/3
从此处开始并从此处逐步降低。有关此说明,请参见标记为“ 改进的范围”的部分。
数学解释
对我而言,立即进行除数测试的原因并不十分明显。如果其他人想知道的话,这是一个解释。
设P
一个大于10
它的最后一个数字为的质数b
。从而
P = 10a + b
在a > 0
和0 <= b < 10
。其实b
要么是1
,3
,7
,或者9
,因为黄金大于10
在这些数字一个必须结束。
现在假设bx + a = 0 (mod P)
。然后
a = -bx (mod P)
10a + b = 10(-bx) + b (mod P)
0 = 10(-bx) + b (mod P)
0 = b(1 - 10x) (mod P)
由于P
是质数,所以整数mod P
是整数域。因此,要么b = 0 (mod P)
,或1 - 10x = 0 (mod P)
。
我们知道0 <= b < 10 < P
,如果b = 0 (mod P)
再b = 0
。但是,我们说b
要么1
,3
,7
,或9
,所以这是不可能的。因此1 - 10x = 0 (mod P)
,如此10x = 1 (mod P)
。换句话说,x
是10
,模的倒数P
。
现在假设N
是一个非负整数,其最后一位是d
,因此N = 10c + d.
我们有一系列等效语句:
10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED。
有用吗?
我还想知道,除数测试(给定N = 10c + d
,替换N
为dx + c
)在实践中是否真的会富有成效。还是至少可以可靠地用N
小于N
(绝对值)的数字代替?
假设N = 10c + d
在哪里c >= 0
和0 <= d < 10
。因此10c = N - d <= N
。通过三角形不等式,
|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|
< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P
因此,如果5P <= 9N/10
,然后|c + dx| < N
。
特别是如果N >= 6P
,则|c + dx| < N
。因此,鉴于P
我们首先计算2P
,3P
,... 6P
,伴随着x
。然后给出N
,我们反复运行试验整除直到我们达到一个数量小于或等于6P
,并检查结果是否是任意的数字0
,P
,2P
,..., 6P
。
(当然,每当达到负数时,我们都用它的绝对值代替它,这是很好的,因为q
可以被P
if和only is整除(-q)
。)
改良绑定
我注意到这|x|/P
似乎从未接近过1/2
。实际上,它似乎总是小于1/3
...或经过仔细检查,它总是非常接近1/10
或3/10
。最大的以往任何时候都得到了似乎是4/13
(发生时P=13
和x=4
)。为什么会这样呢?
设u
一个整数,并假设10u = kP + 1
对于某个整数k
,u
取10
modulo 的逆P
。然后我们也知道k
相对于质数10
,因为k(-P)
等效于1
模10
。
现在,我们知道10
模的反数P
都相差了的倍数P
,因此我们可以取整数u
并随意添加或减去的倍数,P
结果仍然始终是10
模的反数P
。假设我们选择减去P
来自u
:我们得到
10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
换句话说,减少(分别增加)u
由P
对应于减小(增加)k
通过10
。我们希望加/减的倍数P
从u
直到左侧的绝对值最小化; 但是当右侧最小化时,左侧恰好被最小化,因此我们要添加/减去10
,k
直到绝对值最小化右侧。
但我们知道,何时会发生k
之间-5
和5
,因此(因为k
是相对素10
)。这意味着k
要么是-3
,-1
,1
,或3
。(这是OP下@Neil的评论内容。谢谢,尼尔!)
因此,当|u|
被最小化(即u=x
),我们将有x/P = u/P = k/10 + 1/(10P)
,那里k
要么是-3
,-1
,1
,或3
。因此|x|/P <= 3/10 + 1/(10P)
。等效地,|x| <= (3P + 1)/10
。
此外,这种不平等是严格的P=11
,因为P=11
我们有x=-1
和k=-1
。最小的P
为这等式成立的P=13
(这里x=4
和k=3
)。
因此,最大的|x|/P
有史以来得到的是3/10 + 1/(10*13)
,因为P=13
是我们有第一任k=3
,以及那些之中k=3
,在1/(10P)
当期限是最大P
最小(即,P=13
)。因此,对于所有人来说P
,我们也有|x|/P <= 3/10 + 1/130 = 4/13 < 1/3
。这解释了为什么在上面的代码中我们可以在i = P/3
而不是从处开始进行初始化P/2
。
此外,现在可以改善上面“ 有用性”部分中的范围。
引理:让N = 10c + d
地方c > 0
和0 <= d <= 9
。然后c + d|x| < N/10 + 9(3P + 1)/10
。(请注意严格的不等式。)
引理证明:根据情况。案例I:d = 0
是N = 10c
。然后c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10
。
情况二:0 < d <= 9
。然后10c = N - d < N
,这样c < N/10
。因此c + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10
。QED。
因此,如果N > 3P
(和N = 10c + d
以前一样),则
3P + 1 <= N
9(3P + 1)/10 <= 9N/10
N/10 + 9(3P + 1)/10 <= N
c + d|x| < N/10 + 9(3P + 1)/10 <= N
所以,如果N > 3P
那么c + d|x| < N
。
因此,我们只需要找到P
,2P
并且3P
,随着x
。鉴于N > 0
,同时N > 3P
,我们替换N
的|c + dx|
,这降低N
。最终我们会得到N <= 3P
; 在这一点上,我们停下来检查是否N
等于任何数字的0
,P
,2P
,或3P
。
我们不能做得比3P
一般更好。例如,假设P = 13
和N = 39
,所以x = 4
。然后用不变N
的dx + c = 9(4) + 3
树叶代替N
。
x
绝对值最小10*x-1
的输入可被其整除的绝对值。