Как найти первое совершенное число в с

  • В этой теме 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <math.h>
#include <stdio.h>
long sov(long);
long sov(long x)
{
   long i, j, sum;
   short int k;
   //Цикл нахождения ПРОСТОГО числа
   for (i = 2; i <= x; i++)
   {
      sum = 0;
      for (j = 1; j <= sqrt(i); j++)
         if ((i%j == 0) && (i%i == 0))
            sum += 1;
    //Если ПРОСТОЕ число найдено...
      if (sum == 1)
      {
      /*...сравним его с числами 2^k - 1. Если числа равны, умножим число на i.
      Результатом будет совершенное число*/
         for (k = 2; k <= 128; k++)
            if (i == (pow(2, k) - 1))
               printf("Простое: %ldtСовершенное:%.0fn", i, i*(pow(2, k-1)));
       }
    }
}
 
main(void)
{
   sov(524287);
}

Найти совершенные числа

Просмотров 14.7к. Обновлено 15 октября 2021

Найти все совершенные числа до 10000. Совершенное число — это такое число, которое равно сумме всех своих делителей, кроме себя самого. Например, число 6 является совершенным, т.к. кроме себя самого делится на числа 1, 2 и 3, которые в сумме дают 6.

В цикле, перебирая натуральные числа до 10000,

  1. присвоить переменной, в которой будет накапливаться сумма делителей, 0.
  2. В цикле от 1 до половины текущего натурального числа
    1. пытаться разделить исследуемое число нацело на счетчик внутреннего цикла.
    2. Если делитель делит число нацело, то добавить его к переменной суммы делителей.
  3. Если сумма делителей равна исследуемому натуральному числу, то это число совершенно и следует вывести его на экран.

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]

Понравилась статья? Поделить с друзьями:
  • Как найти источник питания для небесного локатора
  • Как найти юридический адрес организации по инн
  • Как найти число среднее арифметическое нескольких чисел
  • Как исправить оценку по изо в 9 классе
  • Как найти vpn на планшете