Міністерство освіти та науки України
Національний університет «Львівська політехніка»
Кафедра ПЗ
КУРСОВА РОБОТА
з курсу «Проблемно-орієнтовані мови програмування»
Варіант 21
Завдання
1. Обчислити суму від’ємних елементів даної матриці, розміщених під головною діагоналлю в стовпцях з парними номерами.
2. Обчислити суми елементів стовпців, номери яких визначаються номерами додатніх елементів заданого вектора.
3. З множини М точок на площині, заданих декартовими координатами на площині, сформувати підмножину P≤M, що містить точки, які знаходяться всередині замкненої області D. Область D обмежена лініями (K – змінний коефіцієнт):
4. З множини прямих М, заданих коефіцієнтами рівняння Ax+By+C=0, сформувати множину прямих P≤M, відстань від яких до точки A(xa; ya) менша за задану величину, і впорядкувати цю множину в порядку зростання відстаней.
5. З множини М точок на площині, сформувати множину точок P≤M, відстань від яких до прямої Ax+By+C=0 найбільша, і впорядкувати цю множину за зростанням відстаней.
6. З множини прямих М, заданих коефіцієнтами рівняння, сформувати множину всіх пар паралельних прямих, відстань між якими належить заданому інтервалу.
7. Визначити довжини ламаних ліній, які починаються в точці A(xa; ya), проходять через одну з точок множини M {(x1; y1), (x2; y2), (x3; y3), ... ,(xn; yn)}. Сформувати множину точок P≤M, що належить ламаним, довжина яких найменша. Впорядкувати цю множину в порядку спадання довжин ламаних.
8. Обчислити методом парабол (Сімпсона) інтеграл
, a = 0,6853; b = 2,0 ... 3,0
9. Обчислити методом Ньютона (дотичних) наближений корінь рівняння:
, αпоч.=0,32; αкінц.=0,4; Δα=0,01; a0=0,1; b0=1,2
Текст програми
Модуль KURS.CPP
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>
#include "zavd4-6.h"
#include "zavd7-9.h"
int VybirZavd();
void Zavd1();
void Zavd2();
void Zavd3();
void main()
{
int zavd;
textcolor(15);
clrscr();
do
{
zavd=VybirZavd(); // Вибiр номера завдання користувачем
switch(zavd)
{
case 1: Zavd1(); break; // 1 - викликаємо функцiю для завд.1
case 2: Zavd2(); break; // 2 - викликаємо функцiю для завд.2
case 3: Zavd3(); break; // ...
case 4: Zavd4(); break;
case 5: Zavd5(); break;
case 6: Zavd6(); break;
case 7: Zavd7(); break;
case 8: Zavd8(); break;
case 9: Zavd9(); break; // 9 - викликаємо функцiю для завд.9
}
}
while (zavd); // Якщо 0 - завершуємо роботу програми
}
int VybirZavd()
{
int task=0;
clrscr();
printf("Номер завдання (0-завершити роботу): ");
// Читаємо номер завдання з клавiатури...
scanf("%d",&task);
// ...i повертаємо його як результат роботи функцiї
return task;
}
void Zavd1()
{
int i,j, n, rezhym, a[50][50], maxpos,s;
FILE *f;
clrscr();
printf("Режим роботи програми (0-звичайний, 1-демонстрацiя): ");
// Задаємо режим роботи програми
scanf("%d",&rezhym);
printf("\n");
if (rezhym!=1) // Якщо "Звичайний" - читаємо данi з клавiатури
{
printf ("Введiть порядок матрицi: "); scanf("%d",&n);
printf ("Введiть елементи матрицi (по рядках)\n");
for (i=0; i<n; i++)
for (j=0; j<n; j++)
scanf("%d",&a[i][j]);
}
else // iнакше - читаємо данi з файлу i виводимо їх на екран
{
f=fopen("z1demo.dat","rt");
printf("Введiть порядок матрицi: ");
fscanf(f,"%d",&n); printf("%d\n",n);
printf ("Введiть елементи матрицi (по рядках)\n");
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
{
fscanf(f,"%d",&a[i][j]);
printf("%d ",a[i][j]);
}
printf("\n");
}
fclose(f);
}
// Обчислюємо суму
s=0;
for (i=0; i<n; i+=2)
{
for (j=i+1; j<n; j++)
if (a[j][i]<0) s+=a[j][i];
}
// Виводимо результати
printf("\nСума: %d\n",s);
printf("\n");
printf("<Enter> - головне меню\n");
// Чекаємо натиснення клавiшi i повертаємося до головного меню
getch();
}
void Zavd2()
{
int i,j, n,m, rezhym, s, **b, *v, l;
FILE *f;
clrscr();
printf("Режим роботи програми (0-звичайний, 1-демонстрацiя): ");
// Задаємо режим роботи програми
scanf("%d",&rezhym);
printf("\n");
// Видiляємо пам'ять пiд двовимiрний масив
b=(int**)calloc(50,sizeof(int*)); // Видiляємо пам'ять пiд рядки
for (i=0; i<50; i++)
b[i]=(int*)calloc(50,sizeof(int)); // Видiляємо пам'ять пiд стовпцi кожного рядка
// Видiляємо пам'ять пiд вектор v
v=(int*)calloc(50,sizeof(int));
if (rezhym!=1) // Якщо "Звичайний" - читаємо данi з клавiатури
{
printf ("Кiлькiсть рядкiв (M): "); scanf("%d",&m);
printf ("Кiлькiсть стовпцiв (N): "); scanf("%d",&n);
printf ("Введiть елементи матрицi (по рядках)\n");
for (i=0; i<m; i++)
for (j=0; j<n; j++)
scanf("%d",*(b+i)+j);
printf ("\nВведiть вектор, що складається з %d елементiв: ",n);
for (i=0; i<n; i++)
scanf("%d",v+i);
}
else // iнакше - читаємо данi з клавiатури i виводимо їх на екран
{
f=fopen("z2demo.dat","rt");
printf ("Кiлькiсть рядкiв (M): ");
fscanf(f,"%d",&m); printf("%d\n",m);
printf ("Кiлькiсть стовпцiв (N): ");
fscanf(f,"%d",&n); printf("%d\n",n);
printf ("Введiть елементи матрицi (по стовпцях)\n");
for (i=0; i<m; i++)
{
for (j=0; j<n; j++)
{
fscanf(f,"%d",*(b+i)+j);
printf("%d ",*(*(b+i)+j));
}
printf("\n");
}
printf ("\nВведiть вектор, що складається з %d елементiв: ",n);
for (i=0; i<n; i++)
{
fscanf(f,"%d",v+i);
printf("%d ",*(v+i));
}
printf("\n");
fclose(f);
}
printf("\n");
for (i=0; i<n; i++)
{
// Обчислюємо суму елементiв стовпця, якщо вiдповiдний
// елемент вектора v - додатнiй
s=0;
if (v[i]>0)
{
for (j=0; j<m; j++)
s=s+*(*(b+j)+i);
// Виводимо суму
printf ("Сума елементiв стовпця %d: %d\n",i+1,s);
}
}
printf("\n");
printf("<Enter> - головне меню\n");
// Чекаємо натиснення клавiшi i повертаємося до головного меню
getch();
}
void Zavd3()
{
int i,n;
float m[50][2], k;
clrscr();
// Вводимо данi (кiлькiсть точок множини та їх координати)
printf("Кiлькiсть елементiв множини M: "); scanf("%d",&n);
printf("Введiть координати %d точок [X Y]\n",n);
for (i=0; i<n; i++)
{
scanf("%f %f",&m[i][0],&m[i][1]);
}
// Виконуємо для кожного значення К окремi обчислення...
for (k=0.1; k<=0.5; k+=0.1)
{
printf("\n");
printf("K=%.1f: ",k);
for (i=0; i<n; i++)
{
// Якщо точка лежить в областi D - виводимо її координати
if ((0.2*m[i][0]-k<=cos(m[i][0]+0.25))
&& (0.2*m[i][0]-k<=m[i][0]) && (m[i][0]>-0.5) && (m[i][0]<=1.5))
printf("(%.3f;%.3f),",m[i][0],m[i][1]);
}
}
printf("\n");
printf("<Enter> - головне меню\n");
// Чекаємо натиснення клавiшi i повертаємося до головного меню
getch();
}
Модуль ZAVD4-6.CPP
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include "zavd4-6.h"
// Вiдстань вiд точки до прямої
float Vidstan1(prjama p, float x, float y)
{
return (fabs((p.A*x + p.B*y + p.C)/sqrt(p.A*p.A + p.B*p.B)));
}
// Вiдстань мiж двома точками
float Vidstan2(float x1, float y1, float x2, float y2)
{
return (sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)));
}
void Zavd4()
{
int i,n, b;
prjama m[50], tmp;
float xa,ya, d0;
clrscr();
// Вводимо данi (кiлькiсть прямих множини М та їх коефiцiєнти)
printf("Кiлькiсть елементiв множини M: ");
scanf("%d",&n);
printf("Введiть коефiцiєнти рiвнянь %d прямих [A B C]\n",n);
for (i=0; i<n; i++)
scanf("%f %f %f",&m[i].A,&m[i].B,&m[i].C);
// Читаємо координати точки А та значення вiдстанi d0
printf("xA="); scanf("%f",&xa);
printf("yA="); scanf("%f",&ya);
printf("d0="); scanf("%f",&d0);
printf("\n");
// Впорядковуємо множину М за зростанням вiдстаней до точки А
do
{
b=0;
for (i=0; i<n-1; i++)
{
if (Vidstan1(m[i],xa,ya)>Vidstan1(m[i+1],xa,ya))
{
tmp=m[i];
m[i]=m[i+1];
m[i+1]=tmp;
b=1;
}
}
}
while (b);
for (i=0; i<n; i++)
{
// Якщо вiдстань менша за d0 - виводимо рiвняння прямої
if (Vidstan1(m[i],xa,ya)<d0)
printf("%.2fx + %.2fy + %.2f = 0 (вiддаль: %.3f\n)",m[i].A,m[i].B,m[i].C,Vidstan1(m[i],xa,ya));
}
printf("\n");
printf("<Enter> - головне меню\n");
// Чекаємо натиснення клавiшi i повертаємося до головного меню
getch();
}
void Zavd5()
{
int i,n, b;
to4ka m[50], tmp;
prjama p1;
clrscr();
// Вводимо данi (кiлькiсть точок множини М та їх координати)
printf("Кiлькiсть елементiв множини M: "); scanf("%d",&n);
printf("Введiть координати %d точок [X Y]\n",n);
for (i=0; i<n; i++)
scanf("%f %f",&m[i].x,&m[i].y);
// Читаємо коефiцiєнти прямої А та значення вiдстанi d0
printf("A="); scanf("%f",&p1.A);
printf("B="); scanf("%f",&p1.B);
printf("C="); scanf("%f",&p1.C);
printf("\n");
// Впорядковуємо множину М за зростанням вiдстаней до прямої p1
do
{
b=0;
for (i=0; i<n-1; i++)
if (Vidstan1(p1,m[i].x,m[i].y)>Vidstan1(p1,m[i+1].x,m[i+1].y))
{
tmp=m[i];
m[i]=m[i+1];
m[i+1]=tmp;
b=1;
}
}
while (b);
for (i=0; i<n; i++)
{
// Виводимо координати точок вiдсортованої множини
printf("(%.2f;%.2f), вiддаль: %.3f\n",m[i].x,m[i].y,Vidstan1(p1,m[i].x,m[i].y));
}
printf("\n");
printf("<Enter> - головне меню\n");
// Чекаємо натиснення клавiшi i повертаємося до головного меню
getch();
}
void Zavd6()
{
int i,j,n;
prjama m[50];
float d1,d2;
clrscr();
// Вводимо данi (кiлькiсть прямих множини М та їх коефiцiєнти)
printf("Кiлькiсть елементiв множини M: "); scanf("%d",&n);
printf("Введiть коефiцiєнти рiвнянь %d прямих [A B C]\n",n);
for (i=0; i<n; i++)
scanf("%f %f %f",&m[i].A,&m[i].B,&m[i].C);
printf("\n");
printf("Крайнi точки iнтервалу:\n");
printf("d1="); scanf("%f",&d1);
printf("d2="); scanf("%f",&d2);
// Перебираємо всi можливi пари прямих
for (i=0; i<n; i++)
for (j=i+1; j<n; j++)
{
// Якщо прямi перпендикулярнi, виводимо їх рiвняння
if (((m[i].A/m[i].B)==(m[j].A/m[j].B)) &&
(Vidstan1(m[i],0,-m[j].C/m[j].A)>=d1) &&
(Vidstan1(m[i],0,-m[j].C/m[j].A)<=d2))
{
printf("%.2fx + %.2fy + %.2f = 0\n",m[i].A,m[i].B,m[i].C);
printf("%.2fx + %.2fy + %.2f = 0\n",m[j].A,m[j].B,m[j].C);
printf("Вiддаль: %.3f\n",Vidstan1(m[i],0,-m[j].C/m[j].A));
printf("\n");
}
}
printf("\n");
printf("<Enter> - вихiд\n");
// Чекаємо натиснення клавiшi i повертаємося до головного меню
getch();
}
Модуль ZAVD7-9.CPP
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include "zavd4-6.h"
#include "zavd7-9.h"
// Пiдiнтегральна функцiя для завдання 8
float f8(float x)
{
return (cos(x)/(1+2*x));
}
// Функцiя для завдання 9
float f9(float _alpha,float _x)
{
return (sqrt(_x)-cos(_alpha*_x));
}
// Похiдна вiд функцiї для завдання 9
float f9s(float _alpha,float _x)
{
return (1/(2*sqrt(_x))+_alpha*sin(_alpha*_x));
}
// iнтегрування методом парабол (Сiмпсона)
// (параметри - крайнi точки iнтервалу (a,b) та кiлькiсть елементарних вiдрiзкiв nj)
float Simp(float a, float b, int nj)
{
int i=0;
float S1=0,S2=0, h,xi;
h=(b-a)/nj; // Обчислюємо крок h
S1=a+h;
for (i=1; i<nj/2; i++)
{
xi=a+2*i*h;
S1+=f8(xi+h);
S2+=f8(xi);
}
// Повертаємо наближене значення визначеного iнтеграла
return ((h/3)*(f8(a)+f8(b)+4*S1+2*S2));
}
void Zavd7()
{
int i,n, b;
to4ka m[50], tmp;
float xa,ya, xb,yb, d,d0;
clrscr();
printf("Кiлькiсть елементiв множини M: "); scanf("%d",&n);
printf("Введiть координати %d точок [X Y]\n",n);
for (i=0; i<n; i++)
scanf("%f %f",&m[i].x,&m[i].y);
printf("xA="); scanf("%f",&xa);
printf("yA="); scanf("%f",&ya);
printf("xB="); scanf("%f",&xb);
printf("yB="); scanf("%f",&yb);
printf("\n");
printf("d0="); scanf("%f",&d0);
printf("\n");
do
{
b=0;
for (i=0; i<n-1; i++)
{
d=Vidstan2(xa,ya,m[i].x,m[i].y)+Vidstan2(xb,yb,m[i].x,m[i].y);
if (d<Vidstan2(xa,ya,m[i+1].x,m[i+1].y)+Vidstan2(xb,yb,m[i+1].x,m[i+1].y))
{
tmp=m[i];
m[i]=m[i+1];
m[i+1]=tmp;
b=1;
}
}
}
while (b);
for (i=0; i<n; i++)
{
d=Vidstan2(xa,ya,m[i].x,m[i].y)+Vidstan2(xb,yb,m[i].x,m[i].y);
if (d>d0)
printf("Ламана через точку (%.2f;%.2f): %.3f\n",m[i].x,m[i].y,d);
}
printf("\n");
printf("<Enter> - головне меню\n");
// Чекаємо натиснення клавiшi i повертаємося до головного меню
getch();
}
void Zavd8()
{
int n, nmax;
float a=0.6853, b, r1,r2, di;
float EPS=1e-4;
clrscr();
printf("Максимальна кiлькiсть елементарних вiдрiзкiв (jmax): ");
scanf("%d",&nmax);
printf("Точнiсть обчислення (напр., 0.001): ");
scanf("%f",&EPS);
// Виконуємо обчислення для бiжучого значення b вiд 2.0 до 3.0
for (b=2.0; b<=3.01; b=b+0.2)
{
n=2;
do
{
// Обчислюємо iнтеграл для кiлькостi вiдрiзкiв nj i 2nj
di=fabs((r1=Simp(a,b,n*2))-(r2=Simp(a,b,n)));
n=n*2;
}
// Якщо кiлькiсть вiдрiзкiв бiльша за максимальну,
// або досягнута необхiдна точнiсть - завершуємо обчислення iнтеграла
while (!((n>nmax) || (di<EPS)));
// Виводимо результати
printf("b=%.2f\tI=%f\tnj=%d\te=%f\t",b,r1,n,di);
if (n>nmax) printf("умова виходу: j>jmax\n");
else printf("умова виходу: |Inj-I(nj-1)|<e\n");
}
printf("\n");
printf("<Enter> - головне меню");
// Чекаємо натиснення клавiшi i повертаємося до головного меню
getch();
}
void Zavd9()
{
const float alpha0=0.32, alpha1=0.4, dalpha=0.01;
int n=0, N;
float a0=0.1, b0=1.2, alpha;
float x1,x, hn, EPS=0.001;
clrscr();
printf("Максимальна похибка обчислень (напр., 0.0001): "); scanf("%f",&EPS);
printf("Максимальна кiлькiсть iтерацiй: "); scanf("%d",&N);
printf("\n");
// Виконуємо обчислення для бiжучого значення alpha вiд 0.5 до 1.5
for (alpha=alpha0; alpha<=alpha1+0.001; alpha+=dalpha)
{
x1=b0;
do
{
n++;
hn=-f9(alpha,x1)/f9s(alpha,x1);
// Обчислюємо наближення Xn
x=x1+hn;
// Якщо досягнута точнiсть - завершуємо обчислення
if (fabs(x1-x)<EPS) break;
x1=x;
}
// Якщо досягнута максимальна кiлькiсть iтерацiй - завершуємо обчислення
while (n<=N);
// Виводимо результати
printf("d = %.2f\t->\tx = %f\n",alpha,x);
}
printf("\n");
printf("<Enter> - головне меню");
// Чекаємо натиснення клавiшi i повертаємося до головного меню
getch();
}
Протокол роботи програми
Завдання 1
Режим роботи програми (0-звичайний, 1-демонстрацiя): 1
Введiть порядок матрицi: 5
Введiть елементи матрицi (по рядках)
5 2 -2 1 5
7 4 2 1 7
3 8 -3 0 1
-3 7 -5 2 0
3 -2 5 7 1
Сума: -8
<Enter> - головне меню
Завдання 2
Режим роботи програми (0-звичайний, 1-демонстрацiя): 1
Кiлькiсть рядкiв (M): 5
Кiлькiсть стовпцiв (N): 4
Введiть елементи матрицi (по стовпцях)
6 8 2 3
1 -4 6 4
3 5 6 32
3 4 7 -6
3 5 7 8
Введiть вектор, що складається з 4 елементiв: 1 -7 -1 3
Сума елементiв стовпця 1: 16
Сума елементiв стовпця 4: 41
<Enter> - головне меню
Завдання 3
Кiлькiсть елементiв множини M: 4
Введiть координати 4 точок [X Y]
0.3 0.5
0.5 0.3
1 2
3 4
K=0.1: (0.300;0.500),(0.500;0.300),(1.000;2.000),
K=0.2: (0.300;0.500),(0.500;0.300),(1.000;2.000),
K=0.3: (0.300;0.500),(0.500;0.300),(1.000;2.000),
K=0.4: (0.300;0.500),(0.500;0.300),(1.000;2.000),
K=0.5: (0.300;0.500),(0.500;0.300),(1.000;2.000),
<Enter> - головне меню
Завдання 4
Кiлькiсть елементiв множини M: 3
Введiть коефiцiєнти рiвнянь 3 прямих [A B C]
1 2 -4
5 6 3
3 -5 1
xA=3
yA=4
d0=6
3.00x + -5.00y + 1.00 = 0 (вiддаль: 1.715)
1.00x + 2.00y + -4.00 = 0 (вiддаль: 3.130)
5.00x + 6.00y + 3.00 = 0 (вiддаль: 5.378)
<Enter> - головне меню
Завдання 5
Кiлькiсть елементiв множини M: 4
Введiть координати 4 точок [X Y]
3 6
-4 2
1 4
7 8
A=4
B=-5
C=3
(7.00;8.00), вiддаль: 1.406
(1.00;4.00), вiддаль: 2.030
(3.00;6.00), вiддаль: 2.343
(-4.00;2.00), вiддаль: 3.592
<Enter> - головне меню
Завдання 6
Кiлькiсть елементiв множини M: 5
Введiть коефiцiєнти рiвнянь 5 прямих [A B C]
1 2 5
1 2 10
2 4 6
3 6 100
4 8 15
Крайнi точки iнтервалу:
d1=4
d2=10
1.00x + 2.00y + 5.00 = 0
1.00x + 2.00y + 10.00 = 0
Вiддаль: 6.708
<Enter> - вихiд
Завдання 7
Кiлькiсть елементiв множини M: 5
Введiть координати 5 точок [X Y]
3 4
-5 2
1 6
5 2
5 8
xA=5
yA=-3
xB=2
yB=1
d0=9
Ламана через точку (5.00;8.00): 18.616
Ламана через точку (-5.00;2.00): 18.251
Ламана через точку (1.00;6.00): 14.948
Ламана через точку (3.00;4.00): 10.442
<Enter> - головне меню
Завдання 8
Максимальна кiлькiсть елементарних вiдрiзкiв (jmax): 1000
Точнiсть обчислення (напр., 0.001): 0.001
b=2.00 I=0.107025 nj=1024 e=0.000624 умова виходу: j>jmax
b=2.20 I=0.087768 nj=1024 e=0.000721 умова виходу: j>jmax
b=2.40 I=0.064128 nj=1024 e=0.000818 умова виходу: j>jmax
b=2.60 I=0.037575 nj=1024 e=0.000916 умова виходу: j>jmax
b=2.80 I=0.009469 nj=1024 e=0.001014 умова виходу: j>jmax
b=3.00 I=-0.018947 nj=1024 e=0.001113 умова виходу: j>jmax
<Enter> - головне меню
Завдання 9
Максимальна похибка обчислень (напр., 0.0001): 0.0001
Максимальна кiлькiсть iтерацiй: 100
d = 0.32 -> x = 0.916436
d = 0.33 -> x = 0.912105
d = 0.34 -> x = 0.907734
d = 0.35 -> x = 0.903327
d = 0.36 -> x = 0.898888
d = 0.37 -> x = 0.894422
d = 0.38 -> x = 0.889932
d = 0.39 -> x = 0.885423
d = 0.40 -> x = 0.880897
<Enter> - головне меню