Вам нужно умножить все наименьшие общие множители вместе, но опустить числа, которые можно умножить, чтобы получить любое из остальных.Это означает умножение на все простые числа, меньшие N, с каждым простым числом, возведенным в наивысшую степень <= N. </p>
const unsigned primes[] = {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47
};
unsigned long long answer(unsigned n){ //for your example n=20
if (n>46) return 0; //will overflow 64 bit unsigned long long
unsigned long long tmp, ret = 1;
for (unsigned i = 0; primes[i]<=n;++i){ //each prime less than n
tmp = primes[i];
while ((tmp*primes[i])<=n) //highest power less than n
tmp *= primes[i];
ret *= tmp;
}
return ret;
}
использование: printf("%llu", answer(20));
Если моя математика / код верныэто должно быть быстро и охватывать числа до 46. Если ваш компилятор поддерживает беззнаковое __int128, его можно изменить так, чтобы оно доходило до 88.
Объяснение: Версия TLDR: все числа либо простые, либо могут быть получены путем умножения простых чисел..
Чтобы получить наименьшее общее кратное из набора чисел, вы разбиваете каждое число на его простые множители и умножаете наибольшее число каждого простого числа.
Простые числа меньше 20:2,3,5,7,11,13,17,19
Не простые числа до 20 лет: 4 = 2 * 2 6 = 2 * 3 8 = 2 * 2 * 2 9 = 3 * 3 10 =2 * 5 12 = 2 * 2 * 3 14 = 2 * 2 * 7 15 = 3 * 5 16 = 2 * 2 * 2 * 2 18 = 2 * 3 * 3 20 = 2 * 2 * 5
Из этого мы видим, что максимальное число 2 равно 4, а максимальное число 3 равно 2.
2 до четвертого <= 20 3 в квадрате <= 20 Все способности> 1 из остальных простых чисел большечем 20.
Поэтому вы получаете:
2 * 2 * 2 * 2 * 3 * 3 * 5 * 7 * 11 * 13 * 17 * 19
То, что вы бы увидели, если бы смотрелипеременная tmp в отладчике.
Другая причина, по которой это происходит быстрее, заключается в том, что он избегает модуля и деления (это дорого для многих систем)