Предложите и обоснуйте эффективный алгоритм для проверки делимости большого целого числа на 9 и на 11, объясните, когда и почему эти правила работают, и предложите обобщение для других оснований счисления

27 Окт в 05:43
9 +1
0
Ответы
1
Алгоритм для 9
Правило: целое число делится на 999 тогда и только тогда, когда сумма его цифр делится на 999.
Почему это работает: для основания десять 10≡1(mod9)10\equiv 1\pmod{9}101(mod9), значит для числа NNN с цифрами did_idi (единицы — d0d_0d0 ) имеем
N=∑i≥0di10i≡∑i≥0di(mod9). N=\sum_{i\ge0} d_i 10^i \equiv \sum_{i\ge0} d_i \pmod{9}.
N=i0 di 10ii0 di (mod9).
Поэтому проверка сводится к вычислению суммы цифр по модулю 999.
Эффективный алгоритм (стриминг, не требует хранения всего числа):
1. Инициализировать r:=0r:=0r:=0.
2. Для каждой цифры ddd (с любой стороны): r:=(r+d) mod 9r:= (r + d) \bmod 9r:=(r+d)mod9.
3. В конце NNN делится на 999 тогда и только тогда, когда r=0r=0r=0.
Сложность: O(n)O(n)O(n) по числу цифр, память O(1)O(1)O(1). Можно ускорять объединением блоков цифр (читая, скажем, по 9 цифр и беря число по модулю 999), но принцип тот же.
Алгоритм для 11
Правило: NNN делится на 111111 тогда и только тогда, когда альтернирующая сумма цифр делится на 111111 (т. е. разность сумм цифр на чётных и нечётных позициях равна 000 по модулю 111111).
Почему это работает: 10≡−1(mod11)10\equiv -1\pmod{11}101(mod11), поэтому
N=∑i≥0di10i≡∑i≥0di(−1)i(mod11). N=\sum_{i\ge0} d_i 10^i \equiv \sum_{i\ge0} d_i(-1)^i \pmod{11}.
N=i0 di 10ii0 di (1)i(mod11).

Эффективный алгоритм:
1. Инициализировать r:=0r:=0r:=0, знак s:=1s:=1s:=1.
2. Для каждой цифры ddd (идя от младших к старшим или наоборот, просто чередовать знак): r:=(r+s⋅d) mod 11r:= (r + s\cdot d) \bmod 11r:=(r+sd)mod11, затем s:=−ss:=-ss:=s.
3. В конце NNN делится на 111111 тогда и только тогда, когда r≡0r\equiv 0r0.
Альтернатива (универсальный приём): использовать накопление по основанию:
r:=(r⋅10+d) mod 11 r:= (r\cdot 10 + d)\bmod 11
r:=(r10+d)mod11
для последовательного чтения цифр слева направо; в конце проверить r=0r=0r=0. Это тоже работает и обычно наиболее просто реализуется.
Обобщение для других оснований и модулей
Общий факт: для основания счисления bbb и модуля mmm положим r≡b mod mr\equiv b\bmod mrbmodm. Тогда для числа
N=∑i≥0dibi N=\sum_{i\ge0} d_i b^i
N=i0 di bi
имеем
N≡∑i≥0diri(modm). N\equiv \sum_{i\ge0} d_i r^i \pmod m.
Ni0 di ri(modm).
Следствия:
- Если r≡1(modm)r\equiv 1\pmod mr1(modm) (т. е. m∣(b−1)m\mid (b-1)m(b1)), то тест сводится к сумме цифр по модулю mmm (аналог правила для 333 и 999 при b=10b=10b=10).
- Если r≡−1(modm)r\equiv -1\pmod mr1(modm) (т. е. m∣(b+1)m\mid (b+1)m(b+1)), то тест сводится к альтернирующей сумме цифр (аналог для 111111).
- В общем случае порядок элемента rrr по модулю mmm равен некоторому ttt; тогда веса rir^iri периодичны с периодом ttt, и проверка сводится к взвешенной сумме по блокам длины ttt.
Универсальный и эффективный алгоритм для любого mmm: вычислять остаток по модулю mmm методом Горнера по основанию bbb:
1. r:=0r:=0r:=0.
2. Для каждой цифры ddd слева направо: r:=(r⋅b+d) mod mr:= (r\cdot b + d)\bmod mr:=(rb+d)modm.
3. Число делится на mmm тогда и только тогда, когда r=0r=0r=0.
Сложность этого алгоритма O(n)O(n)O(n) по числу цифр, память O(1)O(1)O(1). Он работает для любых b,mb,mb,m (не требуется взаимной простоты), и является практической реализацией всех частных правил, которые получаются при специальных значениях rrr.
27 Окт в 06:40
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир