Как найти количество делителей числа.
Например число
20 -> 1 2 4 5 10 20
1 -> 1 = 1
2 -> 1, 2 = 2
4 -> 1, 2, 4 = 3
5 -> 1, 2 = 2
10 -> 1, 2, 5, 10 = 4
20 -> 1, 2, 4, 5, 10, 10 = 6
1 + 2 + 3 + 2 + 4 + 6 = 18
Как найти количество делителей числа.
Например число
20 -> 1 2 4 5 10 20
1 -> 1 = 1
2 -> 1, 2 = 2
4 -> 1, 2, 4 = 3
5 -> 1, 2 = 2
10 -> 1, 2, 5, 10 = 4
20 -> 1, 2, 4, 5, 10, 10 = 6
1 + 2 + 3 + 2 + 4 + 6 = 18
Откровенно говоря, ничего умнее, чем перебор простых делителей числа до sqrt(N) не вижу. Ну, а потом - перебор сочетаний этих простых делителей в составные делители. Понятно, что при нахождении простого делителя делим число на него и начинаем все сначала. И не менее понятно, что количество всех сочетаний (== количество делителей) есть просто произведение всех степеней простых делителей, увеличенные на 1. Ну, например, 360 = 2^3 * 3^2 * 5^1, так что число делителей (3+1)*(2+1)*(1+1)=24.
Если числа небольшие - можно просто перебор всех подряд делителей до sqrt(N), с учетом, что для каждого такого делителя, отличного от 1, есть соответствующий делитель с обратной стороны от sqrt(N).
Код нужен? :)
Update: пример - вывод количества всех делителей (включая 1 и само число)
O(sqrt(N)), но вот дальше что-то у меня оценка не получается. Но никак не хуже O(sqrt(N)*lg N), нет? тогда выходит O(N*lg N) - что-то в таком духе?
– Harry
Sep 03 '16 at 07:33
p1^k1 * ... * pn^kn, то количество всех делителей, очевидно, равно (k1 + 1) * ... * (kn + 1).
– VladD
Sep 03 '16 at 08:19
Можно, найти алгоритм и немного получше, чем перебор простых делителей числа до sqrt(N).
Обратим внимание на тот факт, что любое число, можно представить как произведение простых множителей, таким образом если мы нашли один простой делитель, то далее нам не надо искать делители N, а надо искать делители от частного N/x, где х - наш простой делитель.
Например так. (Извиняюсь за C#)
uint[] simpl_arr = //массив заполненный простыми числами
public List<int> GetSimpleDividors(uint number)
{
List<int> result = new List<int>();
uint s = Convert.ToUInt32(Math.Ceiling(Math.Sqrt(number)));
for ( int i = 0 ; simple_arr[i] < s ; i++ )
{
if (number % simple_arr[i] == 0)
{
result.Add(simple_arr[i]);
uint quotient = number / simple_arr[i];
var tmp = GetSimpleDividors(quotent);
if (tmp.Count > 0)
{
result.AddRange(tmp);
}
else
{
result.Add(quotent);
}
break;
}
}
return result;
}
Можно в цикле через алгоритм Евклида считать до деления на 0.
До конца цикла проверять результат деления: если остаток от деления равен 0, то прибавить 1 к счётчику.
В счётчике считаем количество делителей.
if(n℅i==0) cout << i;где n - ваше число. Вывод можно организовать в какой нибудь вектор. – Nik Sep 03 '16 at 06:16