Перейти к содержимому

Как найти сумму делителей числа

  • автор:

Анализ алгоритма

Обозначим через σ(n) сумму всех делителей числа n .

· Если n = p (p простое ), то σ ( n) = 1 + p;

· Если n = p a ( p простое ), то σ ( p a ) = 1 + p + p 2 + p 3 + … + p a = ;

Функция σ ( n) является мультипликативной . Если n = , то

σ ( n) = σ ( ) * σ ( ) * … * σ( ) =

Указанную сумму можно записать также в виде

Пример

n = 239 простое, σ( 239 ) = 1 + 239 = 240.

n = 24 = 2 3 * 3, σ ( 24 ) = σ ( 2 3 ) * σ ( 3 ) = (1 + 2 + 4 + 8) * (1 + 3) = 15 * 4 = 60.

Вычислим сумму делителей для n = 24 непосредственно: σ ( 24 ) =

1 + 2 + 3 + 4 + 6 + 8 + 12 + 24 =

1 + 2 + 4 + 8 + 3 * (1 + 2 + 4 + 8) =

(1 + 2 + 4 + 8) * (1 + 3) = 15 * 4 = 60

Реализация алгоритма

Читаем входное значение n.

В переменной i перебираем все простые делители числа n (по условию задачи они не более 1000). Вычисляем сумму делителей числа n по указанной в анализе задачи формуле.

Пусть i – простой делитель n. Находим максимальную степень a, для которой i a делит n.

После выполнения цикла p = i a +1 . Умножаем res на .

res *= (p — 1) / (i — 1);

printf( «%lld\n» ,res);

Java реализация

import java.util.*;

class Main

public static void main(String[] args)

Scanner con = new Scanner(System.in);

long n = con.nextLong();

long res = 1;

for ( int i = 2; i

while (n % i == 0)

res *= (p — 1) / (i — 1);

Количество делителей, сумма делителей

Если a и b взаимно просты, то каждый делитель произведения ab может быть единственным образом представлен в виде произведения делителей a и b, и обратно, каждое такое произведение является делителем ab. Отсюда следует, что функция [math]~\tau[/math] мультипликативна:

[math] ~\tau(ab) = \tau(a) \tau(b) [/math]

Пусть [math] a = ^ ^ \ldots ^[/math] — каноническое разложение числа a, то в силу мультипликативности

Но положительными делителями числа [math]p_i^[/math] являются [math]~\alpha_i+1[/math] чисел [math]1, p_i, \ldots, p_i^[/math] .

[math] ~\tau(n) = (\alpha_1+1) (\alpha_2+1) \ldots (\alpha_k+1) [/math]

Сумма делителей

Определение:
Функция [math]~\sigma (a) [/math] определяется как сумма делителей натурального числа a: [math] ~\sigma (a) = \sum_ d [/math]

Функция [math]~\sigma (a) [/math] мультипликативна по тем же соображениям, что и [math]~\tau (a) [/math]

[math] ~\sigma (ab) = \sigma (a) \sigma(b) [/math]

Найти сумму делителей натурального числа

Основы программирования 2.0

Задача 2.16
Дано натуральное число N. Вывести на экран сумму его делителей. Число 1 считается делителем любого натурального числа. Число N не является делителем числа N.

Эту задачу довольно часто задают в контрольных и прочих студенческих делах. Задача несложная. Однако на её примере начинающие могут кое-чему научиться.

Алгоритм решения довольно простой:

  1. Перебираем в цикле все возможные целые числа от 1 до числа N.
  2. Каждый раз пытаемся делить число N на текущее число. Если оно делится без остатка, то текущее число является делителем числа N. Прибавляем его к итоговой сумме.

Разумеется, сначала подготавливаем необходимые переменные.

Ну а чтобы задачка была поинтереснее, предлагаю дополнительно сделать так, чтобы на экран была выведена не только итоговая сумма делителей числа N, но и сами делители.

Решения на Паскале и С++ представлены ниже. Если кто забыл, что такое натуральное число, то см. здесь.

Краткое описание программы:

  1. Обнуляем переменную Sum, в которой у нас будет итоговая сумма делителей.
  2. Получаем случайное значение и записываем его в переменную N.
  3. Затем запускаем цикл от 1 до N и в каждой итерации цикла вызываем нашу функцию ThisDivider(N, i), которая возвращает TRUE, если число i является делителем числа N. Саму функцию описывать не буду, потому что она достаточно простая.
  4. Если число i является делителем числа N, то к переменной Sum мы прибавляем число i, а к строке Str присоединяем строковое представление числа i, предварительно преобразовав это число в строку. Так мы получаем строку, которая содержит все делители числа N.
  5. Ну и в конце выводим всё на экран.

Обратите внимание, что для использования функции преобразования числа в строку в Паскале надо подключить модуль SysUtils, а в С++ — .

Также обратите внимание на то, как мы преобразуем число в строку на С++. Делается это довольно замысловато. И это ещё не самый сложный способ. В Паскале же всё просто и интуитивно понятно. Ну а в С++, как всегда, всё через зад.

Правда, начиная со стандарта С++ 2011 года (вроде с него), появилась более понятная и приятная функция to_string(). Но плохая новость заключается в том, что далеко не все средства разработки (особенно бесплатные) поддерживают этот стандарт. Поэтому я не стал использовать эту функцию в своей программе.

Решение задачи 2.16 на Паскале
program t216; uses SysUtils; //Подключить этот модуль //**************************************************************** // ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ //**************************************************************** var i : WORD; //Индекс N : WORD; //Число Sum : DWORD = 0; //Сумма Str : string = »; //Строка для делителей //**************************************************************** // ФУНКЦИИ И ПРОЦЕДУРЫ //**************************************************************** //**************************************************************** // Функция принимает число и возможный делитель. // ВХОД: Num — число // Del — возможный делитель // ВЫХОД: TRUE — если Del является делителем числа Num //**************************************************************** function ThisDivider(Num, Del : WORD) : boolean; begin if Del = Num then begin Result := FALSE; Exit; end; Result := (Num mod Del) = 0; end; //**************************************************************** // ОСНОВНАЯ ПРОГРАММА //**************************************************************** begin Randomize; //Запустить генерацию случайных чисел N := Random(High(N)); //Получить случайное число WriteLn(‘N = ‘, N); for i := 1 to N do //В цикле проверить возможные делители begin if ThisDivider(N, i) then //Если это делитель, то begin Sum := Sum + i; //прибавить его к сумме Str := Str + IntToStr(i) + ‘ ‘; end; end; //Вывести на экран WriteLn(‘Dividers : ‘, Str); WriteLn(‘Sum of the divisors = ‘, Sum); WriteLn(‘The end. Press ENTER. ‘); ReadLn; end.

Решение задачи 2.16 на С++ #include #include #include //Подключить этот файл using namespace std; //**************************************************************** // ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ //**************************************************************** unsigned short int N; //Число unsigned long int Sum = 0; //Сумма ostringstream Str; //Строка для делителей //**************************************************************** // ФУНКЦИИ И ПРОЦЕДУРЫ //**************************************************************** //**************************************************************** // Функция принимает число и возможный делитель. // ВХОД: Num — число // Del — возможный делитель // ВЫХОД: TRUE — если Del является делителем числа Num //**************************************************************** bool ThisDivider(unsigned short int Num, unsigned short int Del) < if (Del == Num) return(false); return(0 == (Num % Del)); >//**************************************************************** // ОСНОВНАЯ ПРОГРАММА //**************************************************************** int main(int argc, char *argv[]) < srand(time(0)); //Запустить генерацию случайных чисел N = rand() % USHRT_MAX; //Получить случайное число Str.clear(); cout

как найти сумму всех простых делителей числа БЕЗ массива? [закрыт]

Закрыт. Этот вопрос необходимо уточнить или дополнить подробностями. Ответы на него в данный момент не принимаются.

Хотите улучшить этот вопрос? Добавьте больше подробностей и уточните проблему, отредактировав это сообщение.

Закрыт 3 года назад .
как найти сумму всех простых делителей числа БЕЗ массива? java
Отслеживать
задан 29 сен 2020 в 20:05
Катя, попробуйте сначала ответить на этот вопрос человеческим языком, без кода.
– user176262
29 сен 2020 в 20:13

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

если нет требований к скорости алгоритма, то можно сделать следующее:

  1. определяем максимальное число, до которого могут быть делители числа N — оно равно M = sqrt(N) (привет решету Эратосфена)
  2. делаем цикл I от 2 до М
  3. если число N делится на I, то
  1. повторяем этап 2) до тех пор пока N не будет равно 1
  2. SUM = SUM + 1 (вообще 1 не является простым числом, но иногда его считают)
  3. если на этапе 2) не было найдено ни одного делителя, значит число простое и
  1. если на этапе 2) был найден делитель I , но новый этап 2) надо начинать не с 2, а с I

Отслеживать
ответ дан 29 сен 2020 в 20:15
37.3k 4 4 золотых знака 28 28 серебряных знаков 72 72 бронзовых знака
Это сумма всех делителей, а нужно только простых.
29 сен 2020 в 20:50

@Эникейщик, с какого перепою всех то? например на 4 все равно делиться никогда не будет потому что делится на 2. Т.е. алгоритм каждый этап ищет делитель от 2 до sqrt(N), и после первого найденного начинает следующий этап, таким образом всегда будут только простые делители

29 сен 2020 в 21:00
Ну значит некоторые делители будут суммированы несколько раз. Всё равно не то.
29 сен 2020 в 21:03
А некоторые наоборот не будут подсчитаны.
29 сен 2020 в 21:13

@Эникейщик, а в задаче разве сказано, что простые делители по разу? с какой стати? во всяком случае в теории чисел об этом говорится однозначно и, к примеру, у числа 20 простые делители 2,2,5. А по вашей логике только 2 и 5, так что мне кажется именно вы не правы

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *