- В этой теме 3 ответа, 2 участника, последнее обновление 1 год, 11 месяцев назад сделано .
-
Сообщения
-
-
Целое число называется совершенным, если его сомножители, включая 1 (но не само число) в сумме дают это число. Например, 6 — это совершенное число, так как 6 = 1 + 2 + 3.
Напишите функцию is_perfect, которая определяет, является ли параметр number совершенным числом. Используйте эту функцию в программе, которая определяет и печатает все совершенные числа в диапазоне от 1 до 1000.
#include <iostream> using namespace std; bool is_perfect(int num) { int sum = 0; //в цикле для полученного функцией аргумента //будем находить его сомножители, путем деления его на все //целые числа в интервале от 1 до самого числа for(int j = 1; j < num; j++) { if(num % j == 0) sum += j; } //если число и сумма его сомножителей равны - значит число совершенное if(sum == num) return true; return false; } int main() { for (int i = 1; i < 1000; ++i) { if (is_perfect(i)) { cout << i << endl; } } }
Результат работы программы:
-
1/2
часть цикла функцииis_perfect
работает впустую.
Из теории чисел известно, что все делители произвольного числа меньше половины этого числа, то естьj <= num / 2
, еслиnum : j
иnum != j
.
Учитывая этот факт, можно переписать is_perfect так:bool is_perfect(int num) { int sum = 0; for (int j = 1; j <= num / 2; j++) { if (num % j == 0) { sum += j; } } return sum == num; }
-
Тоже самое на Си:
#include <stdio.h> int main() { int n; printf("n: "); scanf("%d", &n); printf("dividers: "); int dividers_sum = 0; for (int i = 1; i < n; ++i) { if (n%i == 0) { dividers_sum += i; printf("%d ", i); } } printf("ndividers_sum: %dn", dividers_sum); if (dividers_sum == n) { printf("%d is perfect numbern", n); } else { printf("%d is not perfect numbern", n); } return 0; }
-
-
Автор
Сообщения
- Для ответа в этой теме необходимо авторизоваться.
Сообщение от insolent
Ничего подобного. Вводил я 10 000 и программа с успехом находила 4 совершенных числа. А время затратила — пару сек
Да, безусловно, числа 6, 28, 496, 8128 оно находит в первые секунды запука программы, но вот пятое число, равное 33 550 336. Компьютер еще до него не добрался, хотя выполняется программа около 10 с половиной часов. Мне интересно, за какое кол-во времени комп найдёт пятое число. Кто нибудь пробовал?
Добавлено через 9 часов 20 минут
Сообщение от Русдеч
Да, безусловно, числа 6, 28, 496, 8128 оно находит в первые секунды запука программы, но вот пятое число, равное 33 550 336. Компьютер еще до него не добрался, хотя выполняется программа около 10 с половиной часов. Мне интересно, за какое кол-во времени комп найдёт пятое число. Кто нибудь пробовал?
Скажу сразу, по алгоритму, предложенному пользователем insolent, программа будет искать 5, 6, 7 числа очень долго. Я искал по подобному алгоритму. Но, послу многих часов работы программы, она так и не подобралась к 5-му совершенному.
Ниже представлена программа, которая ищет совершенные числа гораздо быстрее — 0m31.203s потраченного времени на поиск 7-ми совершенных против многочасового поиска 5-го (которого он так и не нашёл — мне надоело ждать).
Из википедии: «Алгоритм построения чётных совершенных чисел описан в IX книге Начал Евклида, где было доказано, что число 2^{p-1}(2^p-1) является совершенным, если число 2^p-1 является простым» Отсюда и плясал
C | ||
|
Найти совершенные числа
Просмотров 14.7к. Обновлено 15 октября 2021
Найти все совершенные числа до 10000. Совершенное число — это такое число, которое равно сумме всех своих делителей, кроме себя самого. Например, число 6 является совершенным, т.к. кроме себя самого делится на числа 1, 2 и 3, которые в сумме дают 6.
В цикле, перебирая натуральные числа до 10000,
- присвоить переменной, в которой будет накапливаться сумма делителей, 0.
- В цикле от 1 до половины текущего натурального числа
- пытаться разделить исследуемое число нацело на счетчик внутреннего цикла.
- Если делитель делит число нацело, то добавить его к переменной суммы делителей.
- Если сумма делителей равна исследуемому натуральному числу, то это число совершенно и следует вывести его на экран.
Pascal
совершенное число паскаль
var
i,j,s: word;
begin
for i := 1 to 10000 do begin
s := 0;
for j:=1 to i div 2 do
if i mod j = 0 then
s := s+j;
if s = i then
write(i,' ');
end;
writeln;
end.
6 28 496 8128
Язык Си
#include < stdio.h>
main() {
int i,j,s,l;
for (i=2; i<10000; i++) {
s = 0;
for (j=1; j < i; j++)
if (i%j == 0)
s += j;
if (s == i)
printf("%dn", i);
}
}
Если i поделить на 2, то программа работает неправильно. В Питоне такая же проблема.
Python
совершенные числа python
for i in range(2, 10000):
s = 0
for j in range(1, int(i // 2) + 1):
if i % j == 0:
s += j
if s == i:
print(i)
6
28
496
8128
КуМир
алг совершенные числа
нач
цел i,j,s
нц для i от 1 до 1000
s := 0
нц для j от 1 до div(i,2)
если mod(i,j) = 0 то
s := s + j
все
кц
если s = i то
вывод i, " "
все
кц
кон
Невероятно долгий поиск даже до 1000.
Basic-256
for i=2 to 10000
s = 0
for j=1 to i2
if i%j = 0 then s = s + j
next j
if s = i then print i
next i
6
28
496
8128
Вот, если очень хочется именно считать… пользуясь тем, что все известные на сегодня совершенные числа четные, а еще Эйлер доказал их связь с простыми числами Мерсенна — вот мы и подбираем простые Мерсенна, которые обеспечивают совершенные числа в нужном диапазоне:
Disclaimer: код as is, сваяно на коленке, просто показать, как должно работать. Со всеми тонкостями типоразмеров и прочими просьба справляться самостоятельно и меня не трогать
![]()
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int isOddPrime(unsigned int u)
{
for(unsigned int i = 3; i*i <= u; i+=2)
if (u%i == 0) return 0;
return 1;
}
unsigned int Perfect(unsigned int p)
{
unsigned int Mersenne = (1u << p) - 1;
if (!isOddPrime(Mersenne)) return 0;
return Mersenne*(1u << (p-1));
}
int main()
{
unsigned int a, b;
scanf("%u %u",&a,&b);
for(unsigned int p = 2;;++p)
{
unsigned long long s = (1ull << (2*p-1)) - (1ull << (p-1));
if (s > b) break;
if (s < a) continue;
unsigned int res = Perfect(p);
if (res) printf("%lun",res);
}
}
Вывод к нужному виду (ну, там, -1 если чисел нет и т.п.) приведите сами…
P.S. А вообще, самая правильная программа на эту тему —
#include <stdlib.h>
#include <stdio.h>
unsigned long long perfs[] =
{
6,28,496,8128,33550336,8589869056,
137438691328,2305843008139952128
};
int main()
{
unsigned long long a, b;
scanf("%llu %llu",&a,&b);
int was = 0;
for(int i = 0; i < 8; ++i)
{
if (perfs[i] >= a && perfs[i] <= b)
{
was = 1;
printf("%llun",perfs[i]);
}
}
if (!was) puts("-1");
}
P.P.S. Всю необходимую информацию было очень легко получить, погулявшись, например, в Википедию.
Иногда задают задачи по нахождению совершенного числа.
Как гласит Википедия, Совершенное число это :
натуральное число, равное сумме всех своих собственных делителей (т. е. всех положительных делителей, отличных от самого числа).
Реализация функции на Pascal:
[pascal]
function isPerfectNumber(n: integer): boolean;
var
sum,i : integer;
begin
sum :=0;
if n > 0 then
begin
for i := 1 to n-1 do
begin
if (n mod i = 0) then
sum := sum + i;
end;
if (n = sum) then
isPerfectNumber := true
else
isPerfectNumber := false;
end
else isPerfectNumber := false;
end;
[/pascal]
принимает натуральное число, возвращает true, если число совершенное и false в ином случае. Так же, если ввести отрицательное число, вернет false;
И для примера полный исходный код. Использование этой функции:
[pascal]
program sovershennoe;
var
n : integer;
function isPerfectNumber(n: integer): boolean;
var
sum,i : integer;
begin
sum :=0;
if n > 0 then
begin
for i := 1 to n-1 do
begin
if (n mod i = 0) then
sum := sum + i;
end;
if (n = sum) then
isPerfectNumber := true
else
isPerfectNumber := false;
end
else isPerfectNumber := false;
end;
begin
write(‘Введите число для анализа: ‘);
readln(n);
if (isPerfectNumber(n)) then
writeln(‘Совершенное’)
else
writeln(‘Не совершенное’);
readln;
end.
[/pascal]
Такая же реализация этой функции на C++
[cpp]
bool isPerfectNumber(int n)
{
int sum = 0;
int i;
if (n > 0)
{
for (int i = 1; i < n; i++)
{
if (n % i == 0)
sum += i;
}
if (n == sum)
return true;
else
return false;
}
else return false;
}
[/cpp]
Всё так же.
на C# чуть иначе. Я переработал функцию посчитав, что она перегружена и добавил ключевое слово static
[csharp]
static bool isPerfectNumber(int n)
{
int sum = 0;
if (n < 0)
return false;
for (int i = 1; i < n; i++)
{
if (n % i == 0)
sum += i;
}
if (n == sum)
return true;
return false;
}
[/csharp]
и использование в Console Application
[csharp]
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
if (isPerfectNumber(n))
{
Console.WriteLine(«{0} is perfect»,n);
}
else
{
Console.WriteLine(«{0} is not perfect», n);
}
}
[/csharp]