(Закреслено 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
тоді і лише тоді, коли (-q)
є.)
Поліпшене обмеження
Я помітив, що |x|/P
ніколи не здавалося, що поруч 1/2
. Насправді здавалося, що це завжди менше, ніж 1/3
... або при більш детальному огляді це завжди було дуже близько до 1/10
або 3/10
. Найбільшим, що коли-небудь було, здавалося, 4/13
що буває (коли P=13
і коли x=4
). Чому це було б?
Нехай u
буде цілим числом, і припустимо, що 10u = kP + 1
для деякого цілого числа k
, так u
це обернено 10
модуль 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
. (Це вміст коментаря @ Ніла в рамках ОП. Дякую, Ніл! )
Таким чином , коли |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
.
Випадок II: 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
ділиться на вхід.