Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Алгоритмические основы информатики. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
774 Кб
Скачать

/* Найдите количество четных цифр данного натурального чис-

ла. */

#include <iostream>

using namespace std;int main()

{

int n;

cout<<"input n: "; cin>>n; if (n<=0)

cout<<"error n"<<endl; else

{

int count=0; while (n>0)

{

if ((n%10)%2==0) count++; n/=10;

}

cout<<"answer: "<<count<<endl;

}

return 0;

}

Пример 2. Найдите наибольшую цифру данного натурального числа. Пояснения. Для реализации данного алгоритма используется такой же подход, что и в предыдущем примере. Алгоритм носит циклический характер, причем обработка начинается с младшей цифры, которая выделяется из числа n с помощью операции целочисленного деления (%). Далее, обработанная цифра заданного числа отбрасывается (n/10), дальнейшей обработке в цикле подлежит младшая цифра измененного числа. Условием продолжения цикла является n>0. Обработка младшей цифры числа зависит от поставленной задачи, для решения данной задачи выделенная младшая цифра сравнивается с переменной (max), предназначенной для хранения искомой наибольшей цифры. Следует

заметить, что переменная (max) до цикла инициализирована (max=0).

// Найдите наибольшую цифру данного натурального числа. #include <iostream>

using namespace std; int main()

{

int n;

11

cout<<"input n: "; cin>>n; if (n<=0)

cout<<"error n"<<endl; else

{

int max=0; while (n>0)

{

if ((n%10)>max) max=n%10; n/=10;

}

cout<<"answer: "<<max<<endl;

}

return 0;

}

Пример 3. Найдите произведение цифр натурального трехзначного числа.

// Найдите произведение цифр трехзначного числа.

#include <iostream> using namespace std; int main()

{

int n;

cout<<"input n: "; cin>>n; if (n<100 || n>999) cout<<"error n"<<endl; else

{

int a,b,c;

a=n%10; // первая цифра справа b=(n/10)%10; // вторая цифра справа c=n/100; // убрать две цифры справа int res=a*b*c;

cout<<”result: ”<<res;

}

return 0;

}

12

Пример 4. Дано натуральное число. Вывести на экран сумму и произведение всех цифр заданного натурального числа и среднее арифметическое четных цифр.

Пояснения. Реализация данного алгоритма, в отличие от предыдущего примера, носит циклический характер. В теле цикла (см. Пояснения к примеру 2) выделенная цифра, во-первых, накапливается в переменных s и p, для нахождения соответственно их суммы и произведения, во-вторых, проверяется на четность для нахождения среднего арифметического.

/*Дано натуральное число. Вывести на экран сумму и произведение всех цифр заданного натурального числа и среднее арифметическое четных цифр */

#include <iostream> #include <math.h> using namespace std; int main()

{

int n,s,p; double sa;

s=0; p=1;double k=0;double s1=0; cout<<"n=";cin>>n;

while (n>0)

{

int c=n%10; s+=c; p*=c;

if (c%2==0)

{

s1+=c;

k++;

}

n/=10;

}

cout<<"s="<<s<<" p="<<p<<endl; if (k==0)

cout<<"no";

else

{

sa=s/k;

cout<<"sa="<<sa;

}

13

return 0;

}

Пример 5. Определить сумму S цифр заданного натурального числа

A (А<10000) и A-S.

Пояснения. При написании алгоритма используется цикл с предусловием WHILE, так как заранее неизвестна разрядность заданного числа. Перечислим объекты программы: заданное число (вводим с клавиатуры с проверкой), сумма цифр (до входа в цикл эту переменную следует обнулить), вспомогательная переменная для хранения текущей цифры. Для реализации алгоритма выделения цифр, начиная с младшего разряда используется операции целочисленного деления (/, %). Операция получения остатка от деления (%) на 10 позволит выделить младший разряд, т.е. последнюю цифру в числе, которая в соответствии с условием задачи добавляется к сумме (значение переменной S увеличится на величину, равную последней выделенной цифре). Следующим шагом является уменьшение разрядности числа путем отсечения последней цифры с помощью операции целочисленного деления на 10 (/). Процесс повторяется до тех пор, пока число, полученное при уменьшении разрядности, не достигнет нуля.

// Определить сумму S цифр заданного натурального числа A (А<10000) и A-S.

#include <iostream > #include <conio.h> using namespace std; int main()

{int a,b,s;

cout<<”введите натуральное число”; cin>>n; s=0;b=a;

while (a>0)

{

s=s+n%10;

a=a/10;

}

cout<<”Сумма цифр заданного натурального числа =”<<s; cout <<”Разность между числом и суммой = ”<<b-s; getch();

}

14

Пример 6. Вычислить N! (N – факториал).

Пояснения. Алгоритм, реализованный с использованием рекурсивной функции, приведен в Разделе 3. Рекурсивные алгоритмы.

#include <stdio.h>

int factorial(int n) { int f=1;

for (int i=1;i<=n;i++) f*=i;

return f;

}

int main() { int n;

printf("Enter a number: "); scanf("%d", &n);

printf("%d! = %d\n", n, factorial(n)); return 0;

}

Представленные выше алгоритмы лежат в основе большой группы задач, где те или иные действия необходимо выполнять с отдельными цифрами обрабатываемых чисел

2.2. Алгоритмы нахождения делителей натурального числа

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

ся числа 1, 2, 3, 4, 6 и 12.

Собственным делителем натурального числа называется такой делитель, который больше 1 и меньше самого числа. Например, для числа 12 собственными делителями будут 2, 3 и 6.

Алгоритм нахождения делителей натурального числа N включает

всебя несколько методов:

простейший метод заключается в переборе всех чисел от 1 до N. Для каждого числа мы проверяем, делится ли N на него нацело. Если да, то мы нашли делитель. Этот метод работает достаточно быстро, но не очень эффективен для больших чисел;

метод, основанный на анализе диапазона [1, n/2], так как все делители, кроме самого числа, возможны только в этом диапазоне;

15

наиболее быстрый алгоритм нахождения всех делителей натурального числа основан на анализе отрезка [1; n ] и нахождении пары симметричных чисел, являющихся делителями числа, например: для n=32 парами симметричных делителей являются (1, 32), (2, 16), (4, 8), где первое число в паре (i, j) ищется на отрезке [1, n ], а второе – результат деления числа n на i (n/i). Необходима проверка ситуации, когда значения чисел пары совпадают, в этом случае в качестве делителя выбирается только одно из них;

решето Эратосфена – алгоритм, который позволяет найти все простые делители числа N. Он основан на том, что мы последовательно исключаем из списка числа, кратные простому числу, которое мы уже нашли.Такимобразом,мыполучаемсписок простых делителейчислаN;

факторизация Ферма – алгоритм, основанный на теореме Эйлера. Онпозволяетбыстро находитьделителичислаN,еслионинебольшие;

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

Каждый из этих методов имеет свои преимущества и недостатки,

ивыбор метода зависит от того, какие делители мы хотим найти и какого размера число N.

Пример 1. Найдите все делители данного натурального числа. Пояснения. Рассмотрен алгоритм, выводящий на печать одновре-

менно пару симметричных делителей. Как было отмечено выше, при совпадении значений пары (i=n/i), печатается только одно значение (значение переменной i).

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

#include <iostream> #include <math.h> using namespace std; int main ()

{

int n,t;

cout<<"input n: ";cin>>n; t=sqrt(n);

for (int i=1; i<=t; i++)

{

16

if (!(n%i)) if (i!=n/i)

cout<<i<<" "<<n/i<<" ";

else

cout<<i<<" ";

}

}

Контрольные вопросы

1.Какие существуют алгоритмы нахождения делителей натурального числа?

2.В чем заключается простейший метод нахождения делителей числа?

3.Что такое решето Эратосфена и как оно используется для нахождения делителей числа?

4.В чем суть метода факторизации Ферма и когда его следует

применять?

5. Что такое метод квадратичного решета и каковы его преимущества перед другими методами?

Задачи

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

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

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

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

5.Написать программу, которая разлагает заданное натуральное число на простые множители.

6.Написать программу, которая находит числа-близнецы, используя делители чисел.

7.Написать программу, которая решает проблему совершенных чисел, используя делители чисел.

8.Написать программу для генерации делителей чисел с использованием решета Эратосфена.

17

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

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

11.Построить последовательность из первых N натуральных чисел, делителями которых являются только числа 2,3, 5.

12.Найти наименьшее общее кратное данных двух натуральных

чисел.

13.Исходные данные – последовательность натуральных чисел.

Вконце последовательности – нуль. Составить программу для нахождения наименьшего общего кратного всех членов ряда. Кратным ряда считается наименьшее натуральное число, которое делится без остатка на все члены ряда.

2.3.Алгоритмы обработки «именных» натуральных чисел

2.3.1. Идеи реализации алгоритмов поиска простых чисел

Простое число – это натуральное число, которое имеет ровно два различных делителя: 1 и самого себя. Все остальные числа, которые не являются простыми, называются составными.

Простые числа играют важную роль в криптографии, так как на их основе строятся алгоритмы шифрования данных. Одним из таких алгоритмов является алгоритм RSA, который использует два простых числа для создания ключа шифрования.

Также простые числа используются в факторизации чисел, то есть разложении их на простые множители. Это необходимо для решения различных задач, таких как нахождение чисел-близнецов (простые числа, отличающиеся на 2, например, 3 и 5) или нахождение совершенных чисел (натуральные числа, равные сумме своих делителей).

Существуют разные методы нахождения простых чисел, такие как метод проб и ошибок, решето Эратосфена и другие.

Наивный перебор. Рассмотрим следующий алгоритм к поиску простых чисел. Он заключается в следующем. Начиная с двойки перебираем все числа (k) диапазона от 2 до n−1, будем делить проверяемое число n на k с остатком. Если при каком-то k обнаружится нулевой остаток, значит, n делится на k нацело, и проверяемое число n – составное. Если же при выполнении операции целочисленного деления получаем только ненулевые остатки, значит, исходное число – простое; в этом случае

18

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

Все простые числа, за исключением двойки, нечётные. Если отдельно проверить случай, когда n=2, то в дальнейшем можно перебирать числа с шагом 2. Такой подход приведет к двукратному увеличению производительности программы.

Оптимизированный перебор делителей. Алгоритм перебора де-

лителей можно оптимизировать, учитывая следующее утверждение: наименьший делитель составного числа n не превосходит n . Алгоритм нахождения хотя бы одного делителя на отрезке [2, n ] позволяет сделать вывод, что число n -составное. Отсюда очевидно, что у простого числа нет ни одного делителя на отрезке [2, n ].

Решето Эратосфена. Рассмотрим алгоритм нахождения простых чисел – решето Эратосфена (его приписывают древнегреческому учёному Эратосфену Киренскому).

Расположим числа от 2 до n в таблицу (решето). Зачеркнём сначала чётные числа, следующие после двойки. Двойку обведём. Затем выделим следующее после двойки незачёркнутое число (это будет тройка), далее зачеркнём каждое третье число после тройки (начиная с шести). Снова найдём первое после тройки незачёркнутое число (пятёрку), и после него зачеркнём каждое пятое (начиная с десяти). Будем повторять подобные действия, пока в таблице не останутся либо обведённые, либо зачёркнутые числа. Обведённые числа будут в точности простыми:

19

Обратите внимание: количество зачёркиваний у составного числа – это количество простых делителей (без учёта кратности).

Пример 1. Верно ли, что натуральное число N простое

// Верно ли, что натуральное число N – простое.

#include <iostream> #include <math.h> using namespace std; int main(){

int n;

cout<<"enter number n - ";cin>>n; int d=2;

while((d*d<=n) && n%d!=0) d++;

if (d*d>n) cout<<n<<" - prime";

else cout<<n<<" - not prime"; return 0;

}

Пример 2. Вывести на печать все простые числа, не превышающие заданное натуральное число N.

/* Вывести на печать все простые числа, не превышающие заданное натуральное число N*/

#include <iostream> #include <math.h> using namespace std; int prime(int n)

{ double m=sqrt(n); for (int d=2;d<=m;d++) if (n%d==0)

return 0; return 1;

}

int main()

{

int n,k=0; cout<<"n="; cin>>n;

20

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]