Найти сумму простых делителей числа N
При вводе любого значения ничего не выводится
#include <stdio.h>
#include <conio.h>
int main()
{
int n, sum = 1;
if (scanf("%lf", n) == 0)
{
printf("Incorrect input value");
}
else
{
for (int i = 2; i <= n; i++)
{
int count = 0;
if (n % i == 0)
{
for (int j = 2; j <= i - 1; j++)
{
if (i % j == 0)
{
count += 1;
break;
}
else
{
sum += i;
}
}
}
else
{
break;
}
}
}
printf("%i", sum);
}
Ответы (2 шт):
Автор решения: EOF
→ Ссылка
У Вас есть несколько логических ошибок в коде:
- Почему переменная
sumинициализированная значением1? По идее должно быть0. - Ввод значения через
scanfпроисходит по адресу. К тому же у Вас она ожидает значение с плавающей запятой, а не целое значение. Корректный вызов примерно такой:scanf("%d", &n). - Добавление делителя к сумме должно происходить после проверки числа на простоту, а не в ней. Т.е. строка
sum += i;должна быть за пределами вложенного цикла и выполняться только еслиcount == 0. - Веткой
else {break;}Вы завершаете искать делители после первого не простого делителя. Эта ветка вообще не нужна.
По итогу Ваш код должен иметь примерно такой вид:
#include <stdio.h>
int main()
{
int n, sum = 0;
if (scanf("%d", &n) == 0)
{
printf("Incorrect input value");
}
else
{
for (int i = 2;i <= n; i++)
{
int count = 0;
if (n % i == 0)
{
for (int j = 2; j <= i - 1; j++)
{
if (i % j == 0)
{
count += 1;
break;
}
}
if (count == 0)
{
sum += i;
}
}
}
}
printf("%i", sum);
return 0;
}
Это Ваш код с минимальными изменениями. В таком виде его не очень просто понять с первого взгляда из-за непонятных имён переменных и нагромождении всего в одной функции. Вот для примера Я набросал код, который не тянет на идеальную реализацию, но понять его намного проще (правда без ввода данных с клавиатуры):
#include <stdio.h>
#include <stdbool.h>
// Функция проверки числа на простоту
bool isPrime(int n)
{
for(int i = 2; i * i <= n; i++)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
int main(void)
{
// Наше входное значение
int input = 122;
// Сразу инициализируем сумму двойкой, если наше число чётное,
// иначе инициализируем нулём
unsigned long long sum = input % 2 ? 0ULL : 2ULL;
// Цикл начинается с 3, потому что двойку мы уже учли в инициализации суммы
// и теперь удобно идти только по нечётным числам
for (int currentDivisor = 3; currentDivisor <= input; currentDivisor += 2)
{
// Если число делится на текущий проверяемый делитель без остатка
// и этот делитель является простым числом, то добавляем его к сумме
if (input % currentDivisor == 0 && isPrime(currentDivisor))
{
sum += currentDivisor;
}
}
printf("Sum: %llu\n", sum);
return 0;
}
Автор решения: Harry
→ Ссылка
Я бы делал так:
int main()
{
int n, sum = 0;
if (scanf("%d",&n)==0) return 1;
if (n%2 == 0)
{
sum += 2;
while(n%2 == 0) n/=2; // Делим, пока делится.
}
for (int i = 3; i*i <= n; i+=2) // Только по нечетным, четным n быть уже не может
{
if (n%i == 0)
{
sum += i;
while(n%i == 0) n /= i; // Делим, пока делится. Так и n уменьшается
} // что ускоряет работу...
}
if (n > 1) sum += n; // Если после этого что-то осталось — то это простое
printf("%d\n", sum);
}
Но встает вопрос о кратных делителях. Их не надо учитывать? Например, 18 = 2*3*3. Надо ли 3 считать один раз или два?