Как найти число делителей числа паскаль

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

Если разложение числа на простые множители представить в виде:

a = p1s1p2s2p3s3…pnsn, тогда количество делителей рассчитывается по формуле: 

(s1+1)*(s2+1)*(s3+1)*..*(sn+1)

Для поиска количества делителей необходимо знать, сколько раз встретился каждый простой множитель числа.

Для хранения этих количеств будем использовать массив.

Программа решения задачи на языке Паскаль (эффективная)

var n, j, k: int64; d: integer; a: array of integer;

begin

  writeln(‘Введите число’);

  readln(n);

  d := Milliseconds;

  setlength(a, 100);//кол-во возможных различных множителей

  j := 2; k := 0;

  writeln(‘Множители: ‘);

  while n > 1 do

  begin

    while n mod j = 0 do

    begin

      write(j, ‘ ‘);

      a[k] += 1;

      n := n div j;

    end;

    j := j + 1; 

    if n mod j = 0 then k += 1;

  end;

  writeln;

  //writeln(‘Количество множителей:’);

  //a.Where(j->j<>0).Print;

  //writeln;

  writeln(‘Количество делителей:’);

  n := 1;

  for j := 0 to k do

  begin

    if a[j] <> 0 then n := n * (a[j] + 1);

  end;

  writeln(n);

  writeln(‘Время: ‘,(Milliseconds – d) / 1000,’ с’);

end.

Программа решения задачи на языке Паскаль (неэффективная)

var  j, s, n, d: int64;

begin

  writeln(‘Введите число’);

  readln(n);

  d := Milliseconds;

  s := 2;

  for j := 2 to n div 2 do

    if n mod j = 0 then s := s + 1;

  writeln(‘Количество делителей:’);

  writeln(s);

  writeln(‘Время: ‘,(Milliseconds – d)/1000,’ с’);

end.

Результаты запусков

Эффективная программа

Неэффективная программа

Перейти к содержанию

Вывести количество делителей и делители числа

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

В введенном промежутке натуральных чисел найти те, количество делителей у которых не меньше введенного значения. Для найденных чисел вывести на экран количество делителей и все делители.

Пользователь вводит числовой промежуток — минимальное (a) и максимальное (b) числа. После этого запрашивается искомое количество делителей.

Во внешнем цикле перебираются натуральные числа от a до b. При этом в конце каждой итерации a увеличивается на 1, тем самым приближаясь к b.

В теле внешнего цикла вводится счетчик (m) количества делителей очередного натурального числа. Далее во внутреннем цикле перебираются числа (i) от 1 до a. Если i делит нацело a, то счетчик увеличивается на 1.

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

Pascal

количество делителей числа паскаль


var
a,b,n,m,i: word;

begin
write('Числовой промежуток: ');
readln(a,b);
write('Количество делителей не менее... ');
readln(n);
while a <= b do begin
m := 0;
for i:=1 to a do
if a mod i = 0 then m := m + 1;
if m >= n then begin
write(a,' - ', m,' - ');
for i:=1 to a do
if a mod i = 0 then write(i,' ');
writeln;
end;
a := a + 1;
end;
end.



Числовой промежуток: 21 44
Количество делителей не менее... 5
24 - 8 - 1 2 3 4 6 8 12 24
28 - 6 - 1 2 4 7 14 28
30 - 8 - 1 2 3 5 6 10 15 30
32 - 6 - 1 2 4 8 16 32
36 - 9 - 1 2 3 4 6 9 12 18 36
40 - 8 - 1 2 4 5 8 10 20 40
42 - 8 - 1 2 3 6 7 14 21 42
44 - 6 - 1 2 4 11 22 44

Язык Си


#include
main() {
unsigned int a,b,m,n,i;
printf("Числовой промежуток: ");
scanf("%d%d",&a,&b);
printf("Минимальное количество делителей: ");
scanf("%d",&n);
while (a <= b) {
m = 0;
for (i=1; i<=a; i++)
if (a%i == 0) m += 1;
if (m >= n) {
printf("%d - %d - ", a, m);
for (i=1; i<=a; i++)
if (a%i == 0) printf("%d ", i);
printf("n");
}
a += 1;
}
}



Числовой промежуток: 343 434
Минимальное количество делителей: 20
360 - 24 - 1 2 3 4 5 6 8 9 10 12 15 18 20 24 30 36 40 45 60 72 90 120 180 360
420 - 24 - 1 2 3 4 5 6 7 10 12 14 15 20 21 28 30 35 42 60 70 84 105 140 210 420
432 - 20 - 1 2 3 4 6 8 9 12 16 18 24 27 36 48 54 72 108 144 216 432

Python

количество делителей числа python (питон)


a = int(input("Минимум: "))
b = int(input("Максимум: "))
n = int(input("Минимальное количество делителей: "))
while a <= b:
m = 0
for i in range(1,a+1):
if a%i == 0:
m += 1
if m >= n:
print(a,'-',m,end=' - ')
for i in range(1,a+1):
if a%i == 0:
print(i,end=' ')
print()
a += 1



Минимум: 45
Максимум: 66
Минимальное количество делителей: 7
48 - 10 - 1 2 3 4 6 8 12 16 24 48
54 - 8 - 1 2 3 6 9 18 27 54
56 - 8 - 1 2 4 7 8 14 28 56
60 - 12 - 1 2 3 4 5 6 10 12 15 20 30 60
64 - 7 - 1 2 4 8 16 32 64
66 - 8 - 1 2 3 6 11 22 33 66

Basic-256


input "Минимум: ", a
input "Максимум: ", b
input "Минимальное количество делителей: ", n
while a <= b
m = 0
for i=1 to a
if a%i = 0 then m = m + 1
next i
if m >= n then
print a + " - " + m + " - ";
for i=1 to a
if a%i = 0 then print i + " ";
next i
print
endif
a = a + 1
endwhile



Минимум: 150
Максимум: 177
Минимальное количество делителей: 12
150 - 12 - 1 2 3 5 6 10 15 25 30 50 75 150
156 - 12 - 1 2 3 4 6 12 13 26 39 52 78 156
160 - 12 - 1 2 4 5 8 10 16 20 32 40 80 160
168 - 16 - 1 2 3 4 6 7 8 12 14 21 24 28 42 56 84 168

Хотел написать программу по заданию, но, как оказалось, в который раз я попытался решить практически неразрешимую задачу. Всё никак не мог достичь приемлемой скорости вычислений… Ещё бы. Общее количество делителей заданного числа оказалось равным 2963520000.

Цитата
Сообщение от Mike_Boone
Посмотреть сообщение

и так работает

Работает, конечно. Только считать будет до скончания веков. Или, если переполнение BigInteger аварийно завершает программу, то до момента переполнения переменной i. Если добавить условие окончания нахождения делителей, то выводить все делители на экран программа будет где-то пару лет.

Цитата
Сообщение от Artyom2124
Посмотреть сообщение

Найти все делители

Artyom2124, Вы уверены? Если программа будет выдавать по 1000 делителей в секунду, она будет работать более месяца, и, если делители записывать в текстовый файл, конечный объём файла будет примерно 160 гигабайт (более 170000000000 символов). Сильно сомневаюсь, что такое задание могли дать в каком-либо учебном заведении.

Artyom2124, может быть, нужно найти все простые делители?

Это я сделал. К счастью, максимальный простой делитель Вашего числа сравнительно маленький, и помещается в тип integer. Общее количество делителей числа не помещается в тип integer, для подсчёта указанной величины я использовал тип real.

Программа факторизации Вашего числа, находит все простые делители, их максимальные степени и общее количество делителей числа:

Pascal
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
const
  hor = '+----+---------+-----------+';
 
var
  s, t: string; {делимое, частное}
  i, j, c, k: integer; {делитель, счётчик, остаток от деления, номер делителя}
  q: real; {общее количество всех делителей}
  d, p: array[0..15] of integer; {массивы делителей и максимальных степеней делителей}
 
begin
  d[0] := 1; {"лишний" нулевой элемент массива для упрощения алгоритма}
  {первое делимое (исходное число):}
  s := '196708423126676569286001022355850789704717014605805349202544575890563591254090079162973668806152370560989633700137089767703775820200092605536123071613442454080946743909994972297960260325884838413934893551073244410428771253965567859';
  i := 2; {начинаем поиск простых делителей с наименьшего простого числа}
  k := 0; {пока что простые делители не найдены, поэтому их количество пока 0}
  while s <> '1' do {делим число на простые делители до тех пор, пока число не станет равным 1}
    begin
      t := ''; {текуще частное пока не найдено}
      c := 0; {остаток от деления пока равен 0}
      for j := 1 to length(s) do {цикл деления числа}
        begin
          c := c * 10 - ord('0') + ord(s[j]); {приписываем к остатку текущую цифру}
          t := t + inttostr(c div i); {находим текущую цифру частного}
          c := c mod i {находим следующий остаток}
        end;
      if c = 0 then {если последний остаток равен 0, то}
        begin {число делится на текущий делитель, разбираемся с делителем}
          if d[k] <> i then {если новый делитель, то}
            begin
              inc(k); {увеличиваем номер делителя}
              d[k] := i {и записываем текущий делитель в массив}
            end;
          inc(p[k]); {подсчитываем количество текущих делителей}
          while t[1] = '0' do delete(t, 1, 1); {убираем из частного незначащие нули}
          s := t {и переписываем его в делимое}
        end
      else inc(i); {иначе, если последний остаток не равен 0, увеличиваем делитель на 1}
    end;
  {печатаем простые делители}
  writeln('Prime divisors:');
  writeln(hor);
  writeln('|  # | divisor | max power |');
  writeln(hor);
  for j := 1 to k do writeln('|', j:3, ' |',  d[j]:7, '|':3, p[j]:6, '|':6);
  writeln(hor);
  {находим и печатаем общее количество делителей}
  q := 1;
  for j := 1 to k do q := q * (p[j] + 1);
  writeln;
  write('Total quantity of all divisors = ', q)
end.

На моём древнем ноутбуке в Pascal ABC программа считает примерно 24 секунды, эта же программа, подрихтованная и запущенная в Free Pascal, считает примерно 4 секунды.

Прогон программы

Код

Prime divisors:
+----+---------+-----------+
|  # | divisor | max power |
+----+---------+-----------+
|  1 |   1297  |     6     |
|  2 |   5651  |     2     |
|  3 |   6959  |     5     |
|  4 |  10799  |     2     |
|  5 |  12547  |     1     |
|  6 |  15161  |     4     |
|  7 |  16223  |     1     |
|  8 |  16417  |     4     |
|  9 |  17681  |     4     |
| 10 |  18541  |     4     |
| 11 |  20411  |     6     |
| 12 |  23563  |     6     |
| 13 |  26591  |     7     |
| 14 |  27943  |     1     |
| 15 |  28513  |     3     |
+----+---------+-----------+

Total quantity of all divisors = 2963520000

Первая колонка – номер простого делителя, вторая – величина простого делителя, третья – максимальная степень, при возведении в которую простого делителя, получившееся число всё ещё делит исходное число нацело.
Ниже таблицы – общее количество всех делителей.

Пояснения по количеству делителей: любой делитель числа может быть представлен в виде произведения степеней всех простых делителей числа, степень при конкретном простом делителе может быть от 0 до упомянутой выше максимальной степени. Таким образом, общее количество делителей равно количеству всех возможных комбинаций степеней при всех простых делителях, иными словами, произведению увеличенных на 1 максимальных степеней для каждого простого делителя.

Напоследок, если строго по заданию… Казалось бы, имеет смысл дописать мою программу… Осталось совсем немного: перебрать все степени при простых делителях, и умножить исходную единицу нужное количество раз на каждый простой делитель, и так 2963520000 раз… Короче, сущий пустяк, думаю, за год можно будет найти все делители заданного числа.

Добавлено через 2 часа 3 минуты
Если желаете, можете

Цитата
Сообщение от Artyom2124
Посмотреть сообщение

найти как можно больше положительных делителей заданного числа

хоть вручную. Сначала принимаете все степени равными 0, и получаете первый делитель:
285130279430265910235630204110185410176810164170162230151610125470107990695905651012970
=1

Затем начинаем увеличивать степени, например, в порядке справа налево, и перебираем все возможные комбинации следующим образом: если степень в самом правом сомножителе достигла максимальной по таблице, то обнуляем эту степень, и увеличиваем следующую (вторую справа), и продолжаем в том же духе до тех пор, пока не переполнится и вторая справа степень, тогда увеличиваем третью справа, а вторую справа обнуляем, и так до тех пор, пока набор степеней не будет такой же, как в таблице:

285130279430265910235630204110185410176810164170162230151610125470107990695905651012971
=1297
285130279430265910235630204110185410176810164170162230151610125470107990695905651012972
=1682209
285130279430265910235630204110185410176810164170162230151610125470107990695905651012973
=2181825073
285130279430265910235630204110185410176810164170162230151610125470107990695905651012974
=2829827119681
285130279430265910235630204110185410176810164170162230151610125470107990695905651012975
=3670285774226257
285130279430265910235630204110185410176810164170162230151610125470107990695905651012976
=4760360649171455329
285130279430265910235630204110185410176810164170162230151610125470107990695905651112970
=5651
285130279430265910235630204110185410176810164170162230151610125470107990695905651112971
=7329347

285130279430265910235630204110185410176810164170162230151610125470107990695905651112976
=26900798028467894064179
285130279430265910235630204110185410176810164170162230151610125470107990695905651212970
=31933801

285130279430265910235630204110185410176810164170162230151610125470107990695905651212976
=152016409658872069356675529
285130279430265910235630204110185410176810164170162230151610125470107990695915651012970
=6959

285130279430265910235630204110185410176810164170162230151610125470107990695915651212976
=1057882194816090730653105006311

285133279431265917235636204116185414176814164174162231151614125471107992695955651212976
=1967084231266765692860010223558507897047170146058 05349202544575890563591254090079162973668806152370 56098963370013708976770377582020009260553612307161 34424540809467439099949722979602603258848384139348 93551073244410428771253965567859

Добавлено через 4 часа 36 минут
Хотя… Если применить что-нибудь получше строк, то… Программа на Free Pascal Compiler для печати заданного количества делителей, начиная с делителя с заданным номером:

Pascal
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
const
  nd = 15;
 
type
  arr = array[1..nd] of integer;
 
const
  d: arr = (1297, 5651, 6959, 10799, 12547, 15161, 16223, 16417, 17681, 18541, 20411, 23563, 26591, 27943, 28513);
  p: arr = (6, 2, 5, 2, 1, 4, 1, 4, 4, 4, 6, 6, 7, 1, 3);
  n = 17;
  m = 100000000000000;
  mn = 2963520000;
 
var
  a: array[1..n] of uint64;
  i, j, c, k: integer;
  q, b, v: longword;
  r: arr;
 
begin
  write('Start number (1..', mn, '): ');
  readln(b);
  write('Count (1..', mn, '): ');
  readln(q);
  v := b - 1;
  for i := 1 to nd do
    begin
      r[i] := v mod (p[i] + 1);
      v := v div (p[i] + 1)
    end;
  dec(r[1]);
  repeat {начало цикла вычисления делителей}
    //write(b:10, ' |'); //раскомментировать для печати номеров делителей
    inc(b);
    {вычисляем и печатаем очередной набор степеней для простых делителей}
    dec(q);
    c := 1; {перенос}
    for i := 1 to nd do
      begin
        r[i] += c;
        if r[i] > p[i] then
          begin
            r[i] := 0;
            c := 1
          end
        else c := 0;
        //write(r[i]:2) //раскоментировать для печати набора степеней
      end;
    //writeln; раскомментировать для печати набора степеней
    {пока очередной делитель равен 1}
    a[1] := 1;
    for i := 2 to n do a[i] := 0;
    {перемножаем очередной делитель на каждый простой делитель d[i], r[i] раз}
    for i := 1 to nd do
      for j := 1 to r[i] do
        begin
          for k := 1 to n do a[k] := a[k] * d[i];
          for k := 1 to n - 1 do
            begin
              a[k + 1] := a[k + 1] + a[k] div m;
              a[k] := a[k] mod m
            end
        end;
    {печатаем найденный делитель}
    k := n;
    while a[k] = 0 do dec(k);
    write(a[k]);
    for k := k - 1 downto 1 do
      begin
        c := m div 10;
        while (c > 10) and (c > a[k]) do
          begin
            write('0');
            c := c div 10
          end;
        write(a[k])
      end;
    writeln
  until (q = 0) or (b > mn); {конец цикла вычисления делителей}
  readln
end.

Делитель числа размещается в массиве, который используется в качестве 17-разрядного длинного числа в 100000000000000-ричной системе счисления. Так как основание системы счисления является степенью числа 10, то перевести такое число в десятичное не вызывает никаких проблем. Большее основание системы счисления применить не получилось из-за целочисленного переполнения.
В программе нет проверки вводимых значений.
можно объединить обе программы.
Можно переделать для вывода делителей в файл.
Можно переделать под Pascal ABC, но неохота из-за танцев с бубном ввиду отсутствия в Pascal ABC достаточно ёмкого целочисленного типа.
Проверить программу очень просто: нужно ввести Start number: 2963520000 и Count: 1, и будет напечатан последний делитель заданного числа, а именно, само заданное число.



0



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

Формулировка. Дано натуральное число. Подсчитать общее количество его делителей.

Решение. Задача достаточно похожа на две предыдущие. В ней также необходимо провести перебор в цикле некоторого количества натуральных чисел на предмет обнаружения делителей n, но при этом необходимо найти не первый из них с какого-либо конца отрезка [1, n] (это отрезок, содержащий все числа от 1 до n включительно), а посчитать их. Это можно сделать с помощью счетчика count, который нужно обнулить непосредственно перед входом в цикл. Затем в условном операторе if в случае истинности условия делимости числа n (n mod i = 0) нужно увеличивать счетчик count на единицу (это удобно делать с помощью оператора inc).

Алгоритм на естественном языке:

1)      Ввод n;

2)      Обнуление переменной count (в силу необходимости работать с ее значением без предварительного присваивания ей какого-либо числа)

3)      Запуск цикла, при котором i изменяется от 1 до n. В цикле:

  1. Если n делится на i (то есть, остаток от деления числа n на i равен 0), то увеличиваем значение переменнойcount на 1;

4)      Вывод на экран значения переменной count.

Код:

  1. program CountDiv;
  2. var
  3. i, n, count: word;
  4. begin
  5. readln(n);
  6. count := 0;
  7. for i := 1 to n do begin
  8. if n mod i = 0 then inc(count)
  9. end;
  10. writeln(count)
  11. end.

Пример программы паскаль, которая находит все делители натурального числа и их сумму

Пример программы паскаль, которая находит все делители натурального числа и их сумму

Итак, продолжаю выкладывать наиболее востребованные исходники Паскаль ABC по теме циклы паскаль (FOR). Задача Pascal такая: Дано натуральное число. Найти все его делители и их сумму. Число вводится с клавиатуры, делители выводятся через пробелы, сумма в следующей строке. Допустим диалог с пользователем.

Исходный код программы:

Var n, i, sum: integer;  //Описание переменных
Begin                    //Начло программы
writeln ('Введите число'); //Диалог с пользователем
readln(n);                  //Считывание числа
sum := n;                   //Присваивание сумме значение самого числа (само число - уже делитель самого себя)
writeln('Делители числа:');   //Диалог с пользователем
for i := 1 to n div 2 do      //Цикл For от до половины n
  if (n mod i) = 0 then begin  //Если число делится на i, то выводим
    write(i,'  ');
    sum := sum + i;            //К значению суммы прибавляем делитель
  end;                         //Конец условного оператора if
writeln(n); //Вывод самого числа, т.к. оно тоже делитель
writeln('Сумма делителей: ',sum);  //Вывод суммы делителей
End.                               //Конец программы

Дата: 2013-06-25 10:53:19   Просмотров: 48711

Теги: Паскаль Pascal исходник исходники скачать FOR циклы

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