Алгоритмические основы информатики. Учебное пособие
.pdf13. Автоморфным называется натуральное число, равное числу, которое образуют последние цифры его квадрата. Например, 5, так как 52=25, или 25, так как 252=625. Найти все автоморфные числа на данном отрезке.
2.4. Алгоритмы анализа числовых последовательностей
Приведенные ниже алгоритмы обработки числовых последовательностей используют простую переменную (одну или более) для сохранения элемента числовой последовательности. Алгоритм обработки числовой последовательности носит циклический характер, это либо цикл с заданным числом повторений, если известно количество элементов последовательности, либо цикл с неизвестным числом повторений, где условие окончания цикла определяется из условия задачи.
Пример 1. В простую переменную последовательно вводятся N значений вещественных чисел. Вычислить максимальное значение.
/*В простую переменную последовательно вводятся N вещественных чисел. Вычислить максимальное значение. */
#include <iostream> using namespace std; int main()
{
int n,i;float max,x; cout<<"n = "; cin>>n;
cout<<" enter the first number: ";cin>>max; for (i=2;i<=n;i++)
{
cout<<" enter the next number: "; cin>>x;
if (x>max) max = x;
}
cout<<"max="<<max; return 0;
}
Пример 2. В простую переменную последовательно вводятся N значений вещественных чисел. Определить максимальное значение и количество чисел, равных максимуму.
/* В простую переменную последовательно вводятся N чисел.
31
Определить максимальное значение и количество чисел, равных максимуму. */
#include <iostream> using namespace std; int main()
{
int n,kol;float max,x; cout<<"n = ";cin>>n;
cout<<" enter the first number: "; cin>>max; kol=1;
for (int i=2;i<=n;i++)
{
cout<<" enter the first number: "; cin>>x; if (x==max) kol++;
else
if (x>max)
{
max=x;kol=1;
}
}
cout<<" maximum value "<<max;
cout<<" number of numbers equal to maximum: "<<kol; return 0;
}
Пример 3. В простую переменную последовательно вводятся N значений положительных чисел. Определить:
1.Минимальное значение и порядковый номер последнего числа, равного этому значению.
2.Максимальное значение и порядковый номер первого числа, равного этому значению.
/*В простую переменную последовательно вводятся N положительных чисел. Определить:
1.Минимальное значение и порядковый номер последнего числа, равного этому значению.
2.Максимальное значение и порядковый номер первого числа, равного этому значению.*/
#include <iostream> using namespace std; int main()
{
32
int firstmaxpos, lastminpos,n; float max,min,x;
cout<<"n = ";cin>>n;
cout<<" enter the first number ";cin>>max; min=max; firstmaxpos=1; lastminpos=1;
for (int i=2;i<=n;i++)
{
cout<<" enter the next number "; cin>>x; if (x>max) {firstmaxpos=i; max=x;}
if (x<=min) {lastminpos=i; min=x;}
}
cout<<"max = "<<max;
cout<<" pos = "<<firstmaxpos; cout<<" min = "<<min; cout<<" pos = "<<lastminpos; return 0;
}
Пример 4. В простую переменную последовательно вводятся N значений положительных чисел. Сколько чисел больше своих соседей слева?
/* В простую переменную последовательно вводятся N чисел. Сколько чисел больше своих соседей слева? */
#include <iostream> using namespace std; int main()
{
int n,kol;float pred,x; cout<<"N="; cin>>n; kol=0;
cout<<" enter the first number "; cin>>pred; for (int i=2;i<=n;i++)
{
cout<<" enter the next number "; cin>>x; if (x>pred) kol++;
pred=x;
}
cout<<" more than its neighbors on the left " << kol << " numbers from "<<n<<" possible";
return 0;
}
33
Пример 5. В простую переменную последовательно вводятся числа. Окончание ввода – 0.
Определить сколько чисел больше своих соседей слева и справа.
/*В простую переменную последовательно вводятся числа. Окончание ввода – 0. Определить сколько чисел больше своих соседей слева и справа. */
#include <iostream> using namespace std;
int main()
{
int kol; float pred, sled, x; cout<<"enter two number "<<endl;
cout<<"enter the first number, !=0: ";cin>>pred; cout<<"enter second number, !=0: ";cin>>x; kol=0;
while (x!=0)
{
cout<<"enter the next number ";cin>>sled; if ((x>pred) && (x>sled)) kol++; pred=x;x=sled;
}
cout<<"Otvet: " << kol<<" numbers"; return 0;
}
Пример 6. В простую переменную последовательно вводятся значения N чисел. Все ли числа меньше заданного числа Z?
Пояснения. Из текста примера видно, что для получения результата число итераций зависит от следующих ситуаций: во-первых, цикл может завершиться при вводе числа, значение которого больше заданного Z; во-вторых, он может быть завершен, если среди N вводимых чисел не нашлось ни одного, значение которого больше Z.
Алгоритм реализован с использованием цикла с предусловием.
/*В простую переменную последовательно вводятся N чисел. Все ли числа меньше заданного числа Z? */
#include <iostream>
34
using namespace std; int main()
{
int n,i,kol;bool flag; float z,x; cout<<"n = ";cin>>n;
cout<<"z = ";cin>>z; flag=true;i=0; while (i<n)
{
cout<<" enter the number - ";cin>>x; i++;
if (x>=z) flag=false;
}
if (flag) cout <<"All "; else cout <<"Not all "; cout<<" numbers < z = "<<z;
return 0;
}
Пример 7. В простую переменную последовательно вводятся значения N чисел, отличных от нуля. Положительные или отрицательные числа завершают исходную последовательность? Подсчитайте количество завершающих чисел одного знака?
Пояснения. При составлении алгоритма использованы два счетчика: первый – количество подряд идущих положительных чисел; второй – количество подряд идущих положительных чисел. Особенность алгоритма заключается в том, что при появлении в очередной цепочке проверяемых чисел первого положительного элемента счетчик отрицательных элементов сбрасывается и наоборот. После завершения ввода исходных данных последнее значение переменной, в которую вводились числа последовательности, определяет знак завершающей цепочки и на печать выводится соответствующее значение счетчика.
/* В простую переменную последовательно вводится N чисел, отличных от нуля.
Положительные или отрицательные числа завершают последовательность и сколько их?*/
#include <iostream> using namespace std; int main()
{
35
int n,i,km,kp; float x; cout<<"enter n = "; cin>>n; kp=0;km=0;
for (i=1;i<=n;i++)
{
cout<<" enter number: ";cin>>x; if (x>0)
{
if (kp==0) km=0; kp++;
}
if (x<0)
{
if (km==0) kp=0; km++;
}
}
if (x>0) cout<<"positive numbers in quantity: "<<kp; if (x<0) cout<<"negative numbers in quantity: "<<km; return 0;
}
Задачи
1.Определить, является ли число a делителем числа b?
2.Дано натуральное число. Верно ли, что оно заканчивается нечетной цифрой?
3.Дано натуральное число. Верно ли, что оно заканчивается четной цифрой?
4.Дано трехзначноечисло.Верно ли,чтовсеего цифрыодинаковые?
5.Дано трехзначное число. Определить, есть ли среди его цифр одинаковые.
6.Дано трехзначное число. Определить, какая из его цифр больше: а) первая или последняя; б) первая или вторая; в) вторая или последняя.
7.Дано трехзначное число а. Определить: больше ли заданного числа а произведение его цифр.
8.Дано трехзначное число. Определить: кратна ли пяти сумма его
цифр.
9.Дано трехзначное число. Определить: кратна ли сумма его цифр заданному числу а.
10.Дано четырехзначное число. Определить: кратна ли трем сумма его цифр.
36
11.Дано четырехзначное число. Определить: кратно ли четырем произведение его цифр.
12.Дано трехзначное число N. Проверить, будет ли сумма его цифр четным числом.
13.Дано четырехзначное число. Определить: равна ли сумма двух первых его цифр сумме двух его последних цифр.
2.5. Реализация алгоритмов с неизвестным числом повторений
Когда мы не знаем, сколько итераций должен произвести цикл, нам понадобится цикл с предусловием – while или цикл с постусловием do...while.
Синтаксис цикла while в C++ выглядит следующим образом.
while (Условие) { Тело цикла;}
Группа операторов, образующих тело цикла будет выполняться до тех пор, пока условие, указанное в круглых скобках в заголовке цикла, является истинным. Перейдем к решению задач используя цикл while.
В рассматриваемой ниже задаче мы точно знаем, сколько итераций должен выполнить цикл, хотя очень часто бывают ситуации, когда это значение неизвестно.
Ниже приведен исходный код программы, считающей сумму всех целых чисел от 1 до 1000.
#include <iostream> using namespace std;
int main()
{
setlocale(0, "");
int i = 0; // инициализируем счетчик цикла. int sum = 0; // инициализируем счетчик суммы. while (i < 1000)
{
i++;
sum += i;
}
cout << "Сумма чисел от 1 до 1000 = " << sum << endl; return 0;
}
37
Поясним несколько важных моментов. Задано строгое неравенство в условии цикла и счетчик i инициализирован нулем, так как в теле цикла while происходит на одну итерацию больше, потому он будет выполняться, до тех пор, пока значение счетчика будет удовлетворять условию, при этом последняя итерация выполнится при i=1000. Если бы мы поставили нестрогое неравенство, то цикл бы закончился, когда переменная i стала быравна1001ивыполнилосьбынаоднуитерациюбольше.
Теперь давайте рассмотрим по порядку исходный код нашей программы. Сначала мы инициализируем счетчик цикла и переменную, хранящую сумму чисел.
В данном случае мы обязательно должны присвоить счетчику цикла какое-либо значение, в случае использования цикла for значение счетчика присваивается внутри цикла for, здесь же, если мы не инициализируем счетчик цикла, то в него попадет «мусор» и компилятор в лучшем случае выдаст нам ошибку, а в худшем, если программа собе-
рется – сегфолт (Ошибка сегментации (англ.Segmentation fault,
сокр.segfault, жарг.сегфолт) – ошибка программного обеспечения, возникающая при попытке обращения к недоступным для записи участкам памяти либо при попытке изменить память запрещённым спосо-
бом.) практически неизбежен.
Затем мы описываем условие цикла – «пока переменная i меньше 1000 – выполняй цикл». При каждой итерации цикла значение пере- менной-счетчика i увеличивается на единицу в теле цикла.
Когда выполнится 1000 итераций цикла, счетчик станет равным 999 и следующая итерация уже не выполнится, поскольку 1000 не меньше 1000. Следует отметить, что запись sum += i является укороченной записью sum = sum + i.
Послеокончания выполнения цикла, выводим сообщение сответом. Цикл с постусловием do while очень похож на цикл while. Единственное их различие в том, что при выполнении цикла do while один проход цикла будет выполнен независимо от условия. Решение задачи
на поиск суммы чисел от 1 до 1000, с применением цикла do while.
#include <iostream> using namespace std;
int main ()
{
setlocale(0, "");
int i = 0; // инициализируем счетчик цикла.
38
int sum = 0; // инициализируем счетчик суммы. do {// выполняем цикл
i++;
sum += i;
} while (i < 1000); // пока выполняется условие. cout << "Сумма чисел от 1 до 1000 = " << sum << endl; return 0;
}
Принципиального отличия нет, но если присвоить переменной i значение, большее, чем 1000, то цикл все равно выполнит хотя бы один проход.
2.5.1. Реализация алгоритмов, с использованием цикла с предусловием
Пример 1. Для заданного числа x вычислить первое из чисел после-
довательностиsinx,sinsinx,sinsinsinx, ...,меньшее по модулю 10-2.
/*Для заданного числа x вычислите первое из чисел последова-
тельности sin x, sin sin x, sin sin sin x, ...,меньшее по модулю 10-2. */
#include <iostream> #include <math.h> using namespace std; int main()
{
int x;
cout<<"x = ";cin>>x; float s = x;
while (abs(s)>=0.01)
{
s=sin(s);
}
cout<<"s = "<<s; return 0;
}
Пример 2. Выяснить, имеется ли среди чисел i3 – 17*i*n2 + n3, i= 1,
..., n, хотя бы одно число, которое кратно заданному числу А и не кратно заданному числу В (A≠B). При существовании такого числа вычислите сумму всех тех элементов, которые предшествовали ему.
39
/* Выясните, имеется ли среди чисел i3 – 17*i*n2 + n3, i= 1,
..., n, хотя бы одно число, которое кратно заданному числу А и не кратно заданному числу В (A≠B). При существовании такого числа вычислите сумму всех тех элементов, которые предшествовали ему.*/
#include <iostream> #include <math.h> using namespace std;
int main(){
int a,b,n,i,t; cout<<"a,b= ";cin>>a>>b; cout<<"n= ";cin>>n; bool f=false;
i=0; int s=0;
while (i<n and not f){ i++;
t=pow(i,3)+17*i*pow(n,2)+pow(n,3); if (not((t%a)==0 and (t%b!=0))) s+=t;
else { i++; f=true;
}
}
if (f)
cout<<"s= "<<s; else cout<<"no";
return 0;
}
Пример 3. Известен начальный вклад клиента в банк и процент годового дохода. Определить, через сколько лет вклад превысит заданный размер и каков при этом будет размер вклада.
/*Известен начальный вклад клиента в банк и процент годового дохода. Определить, через сколько лет вклад превысит заданный размер и каков при этом будет размер вклада.*/
#include <iostream> using namespace std;
int main()
{
40
