Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие2013_09_28.doc
Скачиваний:
24
Добавлен:
20.05.2015
Размер:
2.72 Mб
Скачать

Задачи для самостоятельного решения

  1. Вычислить приближённое значение бесконечной суммы

S = + + + …

Вычисления прекратить, когда очередное слагаемое станет меньше заданного числа  = 0.001.

  1. Вычислить приближённое значение числа , используя соотношения:

a) =     … (формула Валлиса).

b) = 1 + + + + …

c) =   …

d) =     …

  1. Вычислить приближенно с заданной точностью  = 0.001, не пользуясь стандартными функциями языка C/C++:

y =

  1. Вычислить приближенно с заданной точностью  = 0.001 значение функции y = по итерационной формуле yi+1 = 1.5yi – 0.5xyi3 , i = 0,1,2,3,…

Принять y0 = . Считать, что требуемая точность достигнута, если yi+1 – yi  .

5. Вычислить приближенно с заданной точностью  = 0.001 значение функции

y = (a > 0, p > 0 целое)

Использовать итерационную формулу Ньютона:

yi+1 = yi + (–yi ) , i = 0,1,2,3,…

Принять y0 = . Считать, что требуемая точность достигнута, если yi+1yi  .

Сравнить полученный результат со значением, вычисленным по соответствующей стандартной библиотечной функции языка С/С++ (pow (a, 1/p) ).

6. Выдать на экран в виде таблицы значения функции F(x), заданной в с помощью ряда Тейлора, вычисленные приближенно с заданной точностью  = 0.001 на отрезке [a, b] с шагом x. Каждая строка таблицы должна содержать значение аргумента x, значение функции F(x) и количество просуммированных членов ряда.

6.1. e–x = = 1 – + – … + (–1)n + … , x<

6.2. cos x = = 1 – + – …, x<

6.3. = = 1 – + – …, x<

6.4. arctg x= = x – + – …, x  1

6.5. ln(1 + x) = = x – + – …, –1 < x  1

6.6. ln = = 2(x + + + …), x < 1

6.7. ln(1 – x) = – = –(x + + + …), –1  x < 1

6.8. ln = 2 = 2( + + + …), x > 1

6.9. arctg x = – + = – – + – + …, x < –1

6.10. arctg x = + = – x + – + …, x  1

6.11. arctg x = + = – + – + …, x > 1

6.12. e–x2 = = 1 – + – … + (–1)n + … , x<

6.13. ln x = 2 = 2( + + + …), x > 0

6.14. ln x = = (x – 1) – + – …, 0 < x  2

9. Программирование алгоритмов с использованием функций

Функции по сути являются строительными блоками, с помощью которых в С/С++ создаются программные проекты. Функция представляет логически завершенную часть программного кода, которая может быть независимо откомпилирована, протестирована и вызвана на выполнение. Функция может иметь формальные параметры, которые при её вызове заменяются на фактические параметры (аргументы).

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

Синтаксис определения функции:

[inline][класс памяти] тип имя ([описание формальных параметров/void])

{

описания;

операторы;

[return [<выражение>]; ]

}

Здесь квадратные скобки указывают, что заключенная в них конструкция может отсутствовать. Описатель inline означает, что код функции при каждом ее вызове встраивается (“монтируется ”) в тело вызывающей программы (в точку вызова). Это должно увеличить быстродействие программы.

В определении функции допускается указание класса памяти static или extern (см. раздел “Описание переменных”). Область действия функции, объявленной со спецификацией класса памяти extern, распространяется на все модули программы, т.е. она может быть вызвана из любой точки любого файла программного проекта (принимается по умолчанию). Если же использован описатель static, то область действия такой функции – только в пределах того файла, в котором она определена.

Описатель тип определяет тип возвращаемого функцией значения. Им может быть любой тип, кроме массива и функции. Возвращаемое функцией значение передается в вызывающую программу оператором return <выражение>. Значение <выражения> и есть результат работы функции. Оно вычисляется, преобразуется к типу возвращаемого значения и возвращается в точку вызова функции. (Тип возвращаемого значения должен быть совместимым с типом данных, используемых в операторе return). Функция может ничего не возвращать в точку вызова. В этом случае её тип должен быть void, а оператор return, размещённый в конце функции, быть пустым, либо он вообще отсутствует. Таким образом, функция завершается и управление передается вызывающей программе при достижении закрывающей фигурной скобки или оператора return.

При описании формальных параметров следует иметь в виду, что каждый из них должен иметь индивидуальный описатель типа, а элементы списка разделяются запятыми, например:

double Geron(double x, double y, double z)

Формальные параметры функции полностью локализованы в ней и недоступны вне функции. Для активизации функции осуществляют её вызов. Чтобы вызвать функцию, достаточно указать ее имя с парой круглых скобок, в которых функции передаётся список фактических параметров (аргументов). Аргументы должны соответствовать формальным параметрам по типу, количеству и порядку их следования; совпадение имён тех и других не имеет значения.

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

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

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

double Geron(double, double, double);

Прототип функции задаёт её имя, типы и число формальных параметров, тип значения, возвращаемого функцией, и, быть может, класс памяти (мы этим атрибутом пользоваться пока не будем). Формальные параметры могут иметь имена, но компилятор их игнорирует.

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

Как уже упоминалось, функция возвращает значение, если при её выполнении достигнут оператор return вида

return<выражение>;

<Выражение> вычисляется, преобразуется, если необходимо, к типу возвращаемого значения, указанному в определении (объявлении) функции, и управление возвращается в точку вызова. Если функция не возвращает результат в точку вызова, то вызов имеет вид самостоятельного оператора, например:

Sleep(time);

В противном случае имя функции со списком фактических параметров используется как составная часть некоторого выражения, например

S = Geron(a,b,f) + Geron(c,d,f);

Список формальных параметров функции и соответственно список аргументов функции при её вызове может отсутствовать, но скобки сохраняются, например: clrscr();

При завершении функции значения формальных параметров и значения локальных переменных функции, полученные ими в процессе работы функции, теряются (если только при её определении не был указан класс памяти static).

Замечание. Вызовы функций могут осуществляться по-разному, в зависимости от наших потребностей. Например, известная функция ввода данных

scanf(“%d %d”, &a, &b);

согласно её синтаксису может быть вызвана так:

int k= scanf(“%d %d”, &a, &b);

Здесь k – количество правильно прочитанных переменных.

Пусть требуется вычислить площадь некоторого выпуклого многоугольника, например, четырёхугольника, с заданными длинами сторон a, b, c, d и диагональю f. Задача будет успешно решена, если мы создадим функцию для вычисления площади некоторого абстрактного треугольника со сторонами x, y, z. Тогда, обратившись к ней дважды, вычислим площади S1 и S2 двух треугольников, состав­ляющих в сумме площадь четырехугольника, и проблема будет полностью решена.

Площадь треугольника с известными длинами сторон x, y, z вычислим, используя формулу Герона:

S = , где p = (x + y + z)/2.

Соответствующая программа с функцией Geron() может иметь показанный ниже вид:

#include <conio.h>

#include <iostream.h>

#include <math.h>

double Geron(double ,double ,double ); // прототип

void main()

{

double a,b,c,d,f;

clrscr();

cout<<"Введи стороны четырехугольника ";

cin>>a>>b>>c>>d;

cout<<"Введи диагональ четырехугольника ";

cin>>f;

cout<<"Его площадь="<<Geron(a,b,f)+Geron(c,d,f);

getch();

}

// Функция «формула Герона»:

double Geron(double x,double y,double z)

{

double p=(x+y+z)/2;

return sqrt(p*(p-x)*(p-y)*(p-z));

}

Задача 53.Программа использует функциюNOD() для нахождения наибольшего общего делителя двух заданных натуральных чиселAиB. Найденное значение использеется для вычисления наименьшего общего кратного (NOK) этих чисел.

// Напомним, что NOK(a,b)= a*b/NOD(a,b)

// Программа отлажена в Visual Studio 2008

#include "stdafx.h"

#include<conio.h>

#include <iostream>

using namespace std;

// Функция вычисления наибольшего общего делителя

unsigned NOD(unsigned a, unsigned b)

{

unsigned r;

//if(a < b){r = a; a = b; b=r;}

while (a % b)

{ r = a % b;

a = b;

b = r;

}

return b;

}

// Основная:

int main()

{

unsigned a, b, nod;

// Устанавливаем локализацию для выходного потока

wcout.imbue( locale( "rus_rus.866" ) );

// Выводим строку на русском !

wcout<<L"Введи 2 натуральных числа ";

cin>>a>>b;

nod=NOD(a, b);

wcout<<L" Наибольший общий делитель = "<<nod<<endl;

wcout<<L" Наименьшее общее кратное = "<<a*b/nod<<endl;

getch(); return 0;

}

Задача 54. Программа делает безуспешную попытку с помощью функцииnoswap() обменять местами значения двух переменных. Программа иллюстрирует тот факт, что параметры — простые переменные (но не массивы и строки!) передаются функциипо значению. Это означает, что любое изменение таких формальных параметров в теле функции никоим образом не влияет на значения соответствующих фактических параметров в вызывающей программе.

// Программа отлажена в Visual Studio 2008

#include "stdafx.h"

#include<conio.h>

#include <iostream>

using namespace std;

// Т.к. функция текстуально расположена в файле после

// точки её вызова, то до вызова функции необходимо

// привести её прототип

void noswap (int a, int b); //указывается прототип функции

int main()

{ int a =5, b = 7;

cout <<"a="<<a<<" b="<<b<<endl;

noswap ( a, b);

cout <<"a="<<a<<" b="<<b<<endl;

getch(); return 0;

}

void noswap (int a, int b)

{

int rab = a; a = b; b = rab;

cout <<"a="<<a<<" b="<<b<<endl;

}

Задача 55.Программа находит в заданном диапазоне натуральных чисел [A,B] все числа–“перевертыши”. Решающую роль в поиске играет функцияrevers(), которая заданное натуральное число N преобразует в натуральное число M, представленное теми же цифрами, что и N, но взятыми в обратном порядке.

// Программа отлажена вVisual Studio 2008 (8.04.2008)

#include "stdafx.h"

#include <conio.h>

#include <iostream>

using namespace std;

unsigned long revers (unsigned long n)

{ int z; unsigned long m = 0;

while(n!=0)

{ z = n%10;

m = m*10 + z;

n = n/10;

}

return m;

}

int main()

{ unsigned long A, B, n, m;

// Устанавливаем локализацию для выходного потока

wcout.imbue( locale( "rus_rus.866" ) );

// Выводим строку на русском языке !

wcout<<L"Введи начало диапазона "; cin>>A;

wcout<<L"Введи конец диапазона "; cin>>B;

wcout<<L"\n Вот числа-перевертыши:\n";

for (n=A; n<B; n++)

{ m = revers(n);

if (m==n)

cout <<n<<endl;

}

getch(); return 0;

}

Задача 56. Программа с помощью собственной функцииletter() преобразует каждую введенную прописную латинскую букву в строчную и наоборот. Другие введенные символы функияletter() оставляет без изменения.

Замечание. Для преобразования букв латинского алфавита в верхний и нижний регистры можно использовать библиотечные функции toupper() и tolover() соответственно.

// Программа отлажена вVisual Studio 2008 (3.05.2008)

#include "stdafx.h"

#include <stdio.h>

#include <iostream>

#include <conio.h>

using namespace std;

// bukva.c функция преобразования букв

char letter(char symbol)

{

if (symbol>='A' && symbol<='Z')

return(symbol | 0x20); // c1=c+32

else if (symbol >= 'a' && symbol <= 'z')

return(symbol & 0xDF); // c1=c-32

else

return(symbol); // нет преобразования

}

int main()

{

char ch;

printf("введи букву\n");

scanf("%c",&ch);

printf("%c-%c",ch,letter(ch));

getch(); return 0;

}

Задача 57.Программа находит максимум из 5-ти чисел.

// Программа отлажена в Borland C++ Builder 6

#include <iostream.h>

#include <conio.h>

// Функция нахождения максимума из 2-х чисел:

float max(float x, float y)

{

if(x>y)

return x;

else

return y;

}

// Основная:

int main()

{

clrscr();

float a, b, c, d, f;

gotoxy(25, 10);

cout<<"Введи 5 чисел \n";

cin>>a>>b>>c>>d>>f;

gotoxy(25, 12);

cout<<"Max = "<< max(a,max(b,max(c,max(d,f))));

getch();return 0;

}

Задача 58.Программа использует собственную функцию what_chr(), чтобы распознать, какая из клавиш была нажата и сообщить ее код ASCII. Обратите внимание, что коды клавиш управления курсором, в отличие от обычных клавиш, занимают в памяти не один, а два байта, первый из которых — нулевой или имеющий код 0xE0.

// Программа отлажена в Borland C++ Builder 6

#include "d:\\My_C_Builder_6\\rus.h"

#include <stdio.h>

#include<conio.h>

//Функция распознает код нажатой клавиши

void what_chr(int ch)

{ if(ch == 0 || ch == 0xE0)

{ ch=getch();printf(rus("Спецклавиша - Расширенный скэн-код %u "),ch);

switch(ch)

{ case 72: printf(rus("Стрелка вверх \n")); break;

case 80: printf(rus("Стрелка вниз \n")); break;

case 75: printf(rus("Стрелка влево \n")); break;

case 77: printf(rus("Стрелка вправо\n")); break;

case 71: printf(rus("Клавиша Home \n")); break;

case 79: printf(rus("Клавиша End \n")); break;

default : printf(rus("Остальные клавиши - сам...сам...\n"));

}

}

else

printf(rus("Обычная клавиша %c"\

"(Код %u)\n"),ch,ch);

}

voidmain()

{

int ch;

clrscr();

do

{

puts(rus("\nВведи символ илиESC"));

what_chr(ch=getch());

}

while (ch != 27);

}

Задача 59. Программа изображает равнобедренный треугольник заданной высоты, заполненный символом ‘*’. Для построения фигуры использована функцияpiramida(). Для позиционирования курсора в заданную позицию строки экрана использован переменный формат, поддерживаемый функцией printf().

// Программа отлажена вVisual Studio 2008 (3.05.2008)

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

// Функция построения треугольника:

void piramida(int h)

{

int k, i;

for(k=0; k<=h; k++)

{ printf("%*c", 40-k, ' '); //переменный формат

for(i=40-k; i<=40+k; i++)

cout<<"*";

cout<<"\n";

}

}

// Основная:

int main()

{

int h;

cout<<"Vvedi visoty ";

cin>>h;

piramida(h);

getch();return 0;

}

Задача 60. Программа изображает равнобедренный треугольник заданной высоты, заполненный символом ‘*’. Вершина треугольника располагается в 40 колонке экрана. Для вывода на экран заданного символа заданное число раз использована функция put_ch().

// Программа отлажена вVisual Studio 2008 (3.05.2008)

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

void put_ch(int m,char ch)

{

while(m>0)

{

putchar(ch);

m--;

}

}

int main()

{

int y, i=0; char x = '*';

cout <<" vvedi visotu";

cin >>y;

while(i<y)

{

put_ch(39-i,' '); // pechat 39-i probelov

put_ch(2*i+1, x); // pechat 2*i+1 simvolov

i++;

cout<<'\n';

}

getch(); return 0;

}

Задача 61.Программа изображает равнобедренный треугольник (пустотелый) заданной высоты. Стороны треугольника нарисованы символом с кодом ASCII 002. Вершина треугольника располагается в 40 колонке экрана. Решающую роль в построении играет функция put_ch(), выводящая на экран заданный символ заданное число раз.

// Программа отлажена вVisual Studio 2008

#include "stdafx.h"

#include <iostream>

#include <conio.h>

using namespace std;

// Функция, выводящая на экран заданный

// символ заданное число раз

void put_ch(char c,int n)

{

while(n--)

putchar(c);

}

int main()

{

int i=0,n;

// Устанавливаем локализацию для выходного потока

wcout.imbue( locale( "rus_rus.866" ) );

// Выводим строку на русском !

wcout<< L"Введи высоту треугольника " ; cin>>n;

for(int k=0; k < 40; k++)

putchar(' ');

putchar('\002');putchar('\n');

while(i<=n)

{

put_ch(' ',39-i);

putchar('\002');

put_ch(' ',2*i+1);

putchar('\002');

putchar('\n');

i++;

}

put_ch(' ',39-i);

put_ch('\002',2*n+5);

getch(); return 0;

}

Задача 62.В следующей программе функцияbyte() преобразует заданное целое число в его двоичный эквивалент. В вызывающей программе тестируемые числа вводятся последовательно до тех пор, пока не будет введен какой-нибудь нечисловой символ, который распознает функция вводаscanf(). (Напомним, что эта функция возвращает в качестве результата количество реально введенных данных).

// Программа отлажена в Visual Studio 2008

#include "stdafx.h"

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

void byte(int n)

{

int i;

for(i=8*sizeof(int)-1; i>=0; i--)

putchar(n&(1<<i) ? '1' : '0');

}

int main()

{

int num ;

printf("Введи число или Q ");

while (scanf("%d",&num)==1)

{

printf("%d будет ", num); byte (num);

printf("\nВведи число или Q ");

}

return 0;

}

Задача 63.Треугольник задан координатами своих вершин (x1, y1), (x2, y2), (x3, y3). Проверить, попадает ли точка с координатами (x4, y4) внутрь этого треугольника.

Соединим тестируемую точку (x4, y4) c вершинами треугольника и вычислим сумму площадей образовавшихся треугольников s1+s2+s3 с площадью исходного треугольника s. Очевидно, что точка внутри, если s=s1+s2+s3. Программа использует две функции: Geron()иdenka()для вычисления площади треугольника и длины отрезка соответственно.

// Программа отлажена в Borland C++ Builder 6

#include<iostream.h>

#include<math.h>

#include<conio.h>

double Geron (double x, double y, double z)

{

doublep=(x+y+z)/2;

return sqrt(p*(p-x)*(p-y)*(p-z));

}

double denka(double k,double l,double z, double m)

{

returnsqrt((z-k)*(z-k)+(m-l)*(m-l));

}

voidmain()

{

floatx1,y1,x2,y2,x3,y3,x4,y4,s,a1,a2,a3,a4,a5,a6,s1,s2,s3,s4;

cout<<"Введи координаты первой точки "; cin>>x1>>y1;

cout<<"Введи координаты второй точки "; cin>>x2>>y2;

cout<<"Введи координаты третьей точки "; cin>>x3>>y3;

cout<<"Введи координаты тестируемой точки "; cin>>x4>>y4;

a1=denka(x3,y3,x1,y1);

a2=denka(x3,y3,x2,y2);

a3=denka(x2,y2,x1,y1);

s=Geron(a1,a3,a2);

a4=denka(x4,y4,x2,y2);

a5=denka(x4,y4,x1,y1);

a6=denka(x4,y4,x3,y3);

s1=Geron(a1,a5,a6);

s2=Geron(a5,a3,a4);

s3=Geron(a2,a6,a4);

s4=s1+s2+s3;

//cout<<"s="<<s<<endl;

//cout<<s1<<endl; cout<<s2<<endl;cout<<s3<<endl;

//cout<<"s1+s2+s3="<<s4<<endl;

//cout<<"fabs(s-s4)="<<fabs(s-s4)<<endl;

if(fabs(s-s4)<0.001)

cout<<"Точка лежит в треугольнике";

else

cout<<"Точка не лежит в треугольнике";

cout<<"\n-----------------------------"<<endl;

getch();

}

Задача 64. Программа с функцией power() обеспечивает возведение натурального числа А в n-ю степень (n–натуральное число). Результат не должен превосходить 232–1.

// Функция находит p=tn

unsignedlongpower(unsignedlongt,unsignedlongn)

{

unsigned long p=1;

while (n != 0)

{

if (n%2 !=0)

p*=t;

n/=2;

t*=t;

}

return (p);

}

/* Возведение в степень-главная программа */

#include <stdio.h>

#include <conio.h>

intmain()

{

intn,a; clrscr();

printf("Введи a, n ");

scanf("%d %d",&a,&n);

printf("%d в степени %d = %lu\n",a,n,power(a,n));

getch(); return0;

}

Задача 65.Программа с функцией proso() находит в заданном диапазоне [1, m] все простые числа.

// Программа отлажена в Visual Studio 2008

#include "stdafx.h"

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

#include <math.h>

int proso(int k)

{

int i=3;

if(k%2 == 0) return 0; //четное

for(i=3;i<k/2; i+=2)

if(k%i==0) return 0;

return 1;

}

int main()

{

int m,i; setlocale(NULL, ".1251");

printf("Введи m ");

scanf("%d",&m);

for (i=1;i<m;i+=2)

if(proso(i)) printf("%d - простое\n",i);

return 0;

}

Задача 66.Программа позволяет найти в заданном промежутке все совершенные числа. Напомним, что натуральное число называютсовершенным, если оно равно сумме всех своих делителей, не считая его самого. Известно, что все совершенные числа — четные и что первое совершенное число из натурального ряда равно 6. Этим объясняется правило изменения параметра внешнего цикла. Так как все натуральные числа имеют своим делителем единицу, полагаем начальное значение суммы делителей числа S = 1. Во внутреннем цикле организуется перебор всех множителей текущего значения N. Из теории чисел известно, что такому испытанию имеет смысл подвергать числа от 2 до N/2, либо даже до . Это не очень совершенный алгоритм. Более эффективный алгоритм будет реализован в следующей задаче.

#include <stdio.h>

#include <conio.h>

#include <dos.h>

intmain()

{

unsigned long j,n,M,S;

struct time t;

clrscr();

printf("ВВЕДИ M\n");

scanf("%lu",&M);

n=4;

gettime(&t);

printf("The current time is: %2d:%02d:%02d.%02d\n",

t.ti_hour, t.ti_min, t.ti_sec, t.ti_hund);

while(n <= M)

{

S=1; j=2;

while(j <= n/2)

{

if(n%j == 0)

S=S+j;

j++;

}

if(n == S)

printf("%lu-СОВЕРШЕННОЕ\n",n);

n+=2;

}

gettime(&t);

printf("The current time is: %2d:%02d:%02d.%02d\n",

t.ti_hour, t.ti_min, t.ti_sec, t.ti_hund);

getch();

return0;

}

В программе использован новый тип данных – структура, который подробно будет обсуждаться позже. Здесь он использован для доступа к служебной структуре, хранящей системное время. – структура0000000000000000000000000000000000000000000000000000000000000000000000000000

Задача 67. Программа позволяет найти в заданном интервале все совершенные числа. Используется алгоритм нахождения совершенных чисел, более эффективный по сравнению с приведенным ранее. Этот алгоритм основан на известном из теории чисел утверждении Ферма о том, что если натуральное числоp = 2k+1– 1 простое, то число

n= 2k.(2k+1– 1) =p.2k— совершенное (k = 1,2,...).

Функция proso определяет, является ли число pпростым; функция power() служит для возведения натурального числа в степень и представляет самостоятельный интерес (впрочем, для той же цели подойдет и стандартная функция pow()). Обратите внимание, что функция proso() проверяет в качестве возможных делителей исходного числа только нечетные числа, так как само испытуемое число - нечетное. Отметим, что это очень эффективный алгоритм: приведенные в задаче результаты были получены программой на нашем компьютере (процессор AMD AthlonXP 2000+ 1.7GHz) практически мгновенно. Программа из предыдущей задачи за разумное время этого сделать не может.Вывод: если алгоритм плохой, то программа хорошей быть не может.

// Программа отлажена в Borland C++ Builder 6

/* Найти все совершенные числа, не превосходящие 232– 1 */

#include <stdio.h>

#include <conio.h>

#include<math.h>

/* Функция возведения t в n-ю степень */

unsigned long power(unsigned long t, unsigned long n)

{

unsigned long p=1;

while (n != 0)

{

if (n%2 !=0)

p=p*t;

n/=2;

t*=t;

}

return(p);

}

intmain()

{

clrscr();

int proso(unsigned long);

unsigned long K,P,N;

K=1;

while (K <=17)

{

N = power(2,K); // либо N=pow(2,K);

P = 2*N-1;

if(proso(P))

printf("%lu-СОВЕРШЕННОЕ\n",N*P);

K++;

}

getch(); return0;

}

/* Подпрограмма определяет, является

ли число n простым */

int proso(unsigned long n)

{

unsigned long i=3;

while (i < n/2)

{

if(n%i == 0)

return(0);

i+=2;

}

return(1);

}

Результаты:

6-СОВЕРШЕННОЕ

28-СОВЕРШЕННОЕ

496-СОВЕРШЕННОЕ

8128-СОВЕРШЕННОЕ

33550336-СОВЕРШЕННОЕ

4294901760-СОВЕРШЕННОЕ

Далее приведены примеры программ, реализующих некоторые численные методы вычисления корней нелинейных уравнений. Сделаем некоторые предварительные пояснения.