(删除的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可以被Pif和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取10modulo 的逆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的输入可被其整除的绝对值。