Ну вот, движок построили, теперь на этом движке начинаем решать задачи.

void CP11Doc::ha ()
{
int a, b, c;
int m;
double d, e, f, g, h, i;
CString j;
int p [20];
if (af == 1)
{
/* 67.1.34.18. Получить на экране десятичные коды букв латинского алфавита. */
ic [4] = "18. ";
for (a = 'a'; a <= 'z'; a++)
{
j.Format ("%c %i", a, a);
ic [4] += j;
if (a < 'z') ic [4] += ", ";
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * 1 */
if (af == 2)
{
/* 11.1.1. */
ia [0] = ka * kd;
ia [1] = kb * kc;
/* 13.1.2. Составить алгоритм решения квадратного уравнения: ax^2 + bx + c = 0. */
if (ka == 0)
if (kb == 0)
if (kc == 0)
a = 3;
else
a = 0;
else
{
a = 1;
d = (double) -kc / kb;
}
else
{
b = kb * kb - 4 * ka * kc;
if (b < 0)
a = 0;
else
if (b == 0)
{
a = 1;
d = -kb / 2. / ka;
}
else
{
a = 2;
d = (-kb - sqrt (b)) / 2 / ka;
e = (-kb + sqrt (b)) / 2 / ka;
}
}
switch (a)
{
case 0: ic [0].Format ("2. Нет решений."); break;
case 1: ic [0].Format ("2. x = %.4g.", d); break;
case 2: ic [0].Format ("2. x1 = %.4g, x2 = %.4g.", d, e); break;
default: ic [0].Format ("2. Решение - любое число.");
}
/* 16.1.3. Вычислить n! */
a = 1;
b = ka + 1;
if (b > 20) b = 20;
for (c = 1; c < b; c++) a *= c;
ia [2] = a;
/* 18.1.4. Даны два натуральных числа M и N. Вычислить их наибольший общий делитель НОД (M, N). */
la = ka; lb = kb; lc = kc;
if (la < 0) la = -la; if (!la) la = 1;
if (lb < 0) lb = -lb; if (!lb) lb = 1;
if (lc < 0) lc = -lc; if (!lc) lc = 1;
a = la; b = lb;
while (a - b) if (a > b) a -= b; else b -= a;
ia [3] = a;
/* 21.1.6. Даны декартовы координаты трёх вершин треугольника на плоскости. Составить алгоритм определения площади треугольника. */
d = ma (ka, kb, kc, kd);
e = ma (ka, kb, ke, kf);
f = ma (kc, kd, ke, kf);
ib [1] = mb (d, e, f);
/* 21.3.8. Даны три положительных числа. Составить алгоритм, определяющий, могут ли они быть длинами сторон треугольника. */
if (ka > 0 && kb > 0 && kc > 0 && ka + kb > kc && ka + kc > kb && kb + kc > ka)
ic [2].Format ("8. Числа могут быть длинами сторон треугольника.");
else
ic [2].Format ("8. Числа не могут быть длинами сторон треугольника.");
/* 21.4.9. Пусть компьютер способен выполнять только две арифметические операции - сложение и вычитание. Составить алгоритмы: а) умножения двух целых чисел; б) целочисленного деления двух чисел; в) получения остатка от целочисленного деления двух чисел. */
a = 0;
for (b = 0; b < lb; b++) a += la;
ia [4] = a;
a = la;
b = 0;
while (a >= lb) {a -= lb; b++;}
ia [5] = b;
ia [6] = a;
/* 21.5.10. Построить алгоритм решения биквадратного уравнения, используя как вспомогательный алгоритм решения квадратного уравнения. */
if (ka == 0)
if (kb == 0)
if (kc == 0)
a = 5;
else
a = 0;
else
{
d = (double) -kc / kb;
if (d < 0) a = 0;
else if (d == 0) {a = 1; f = 0;}
else {a = 2; f = -sqrt (d); g = sqrt (d);}
}
else
{
b = kb * kb - 4 * ka * kc;
if (b < 0)
a = 0;
else
if (b == 0)
{
d = -kb / 2. / ka;
if (d < 0) a = 0;
else if (d == 0) {a = 1; f = 0;}
else {a = 2; f = -sqrt (d); g = sqrt (d);}
}
else
{
d = (-kb - sqrt (b)) / 2 / ka;
e = (-kb + sqrt (b)) / 2 / ka;
if (d < 0)
if (e < 0) a = 0;
else if (e == 0) {a = 1; f = 0;}
else {a = 2; f = -sqrt (e); g = sqrt (e);}
else
if (d == 0)
if (e < 0) {a = 1; f = 0;}
else {a = 3; f = -sqrt (e); g = 0; h = sqrt (e);}
else
if (e < 0) {a = 2; f = -sqrt (d); g = sqrt (d);}
else if (e == 0) {a = 3; f = -sqrt (d); g = 0; h = sqrt (d);}
else {a = 4; f = -sqrt (e); g = -sqrt (d); h = sqrt (d); i = sqrt (e);}
}
}
switch (a)
{
case 0: ic [3].Format ("10. Нет решений."); break;
case 1: ic [3].Format ("10. x = %.4g.", f); break;
case 2: ic [3].Format ("10. x1 = %.4g, x2 = %.4g.", f, g); break;
case 3: ic [3].Format ("10. x1 = %.4g, x2 = %.4g, x3 = %.4g.", f, g, h); break;
case 4: ic [3].Format ("10. x1 = %.4g, x2 = %.4g, x3 = %.4g, x4 = %.4g.", f, g, h, i); break;
default: ic [3].Format ("10. Решение - любое число.");
}
/* 21.6.11. Составить алгоритм нахождения НОД трёх натуральных чисел, используя вспомогательный алгоритм нахождения НОД двух чисел. */
a = la; b = lb;
while (a - b) if (a > b) a -= b; else b -= a;
b = lc;
while (a - b) if (a > b) a -= b; else b -= a;
ia [7] = a;
/* 33.1.12. Оттранслируйте с алгоритмического языка алгоритм выбора наибольшего значения из трёх. */
a = ka;
if (a < kb) a = kb;
if (a < kc) a = kc;
ia [8] = a;
/* 48.9.21.13. Присвоить целой переменной h значение цифры, стоящей в разряде сотен в записи положительного целого числа k (например, если k = 28796, то h = 7). */
ia [9] = ka % 1000 / 100;
/* 48.10.22.14. Целой переменной S присвоить значение суммы цифр трёхзначного целого числа k. */
a = ka % 1000;
ia [10] = a / 100 + a / 10 % 10 + a % 10;
/* 63.1.31.15. По длинам трёх сторон треугольника a, b, c вычислить его площадь. */
ib [2] = mb (ka, kb, kc);
/* 65.1.33.17. Вычислить сумму целых чисел от M до N путём прямого суммирования. Здесь M и N - целые числа. */
a = 0;
for (b = ka; b <= kb; b++) a += b;
ia [11] = a;
/* 71.7.47.21. Даны два натуральных числа a и b. Определить наибольший общий делитель трёх величин: a + b, |a - b|, ab. */
a = ka + kb;
b = ka - kb;
c = ka * kb;
if (b < 0) b = -b;
if (a < 2 || b < 2 || c < 2) ia [14] = 1;
else
{
while (a - b) if (a > b) a -= b; else b -= a;
while (a - c) if (a > c) a -= c; else c -= a;
ia [14] = a;
}
/* 80.1.48.22. Составить программу вычисления площади кольца по значениям внутреннего и внешнего радиусов, используя подпрограмму вычисления площади круга (2 варианта: с процедурой и с функцией). */
ib [4] = 3.141592653589 * (kb * kb - ka * ka);
/* 80.2.49.23. По координатам вершин треугольника вычислить его периметр, используя подпрограмму вычисления длины отрезка, соединяющего две точки. */
ib [5] = ma (ka, kb, kc, kd) + ma (ka, kb, ke, kf) + ma (kc, kd, ke, kf);
/* 80.3.50.24. Даны три целых числа. Определить, сумма цифр которого из них больше. Подсчёт суммы цифр организовать через подпрограмму. */
a = na (ka); b = na (kb); c = na (kc);
if (a >= b && a >= c)
ic [5].Format ("24. Сумма цифр первого числа больше.");
else
if (b >= c)
ic [5].Format ("24. Сумма цифр второго числа больше.");
else
ic [5].Format ("24. Сумма цифр третьего числа больше.");
/* 80.4.51.25. Определить площадь выпуклого четырёхугольника по заданным координатам вершин. Использовать подпрограмму-процедуру вычисления площади треугольника по формуле Герона. */
// Считаем векторы сторон четырёхугольника
p [0] = kc - ka; p [1] = kd - kb; p [2] = ke - kc; p [3] = kf - kd;
p [4] = kg - ke; p [5] = kh - kf; p [6] = ka - kg; p [7] = kb - kh;
// Считаем векторные произведения смежных сторон четырёхугольника
p [8] = p [0] * p [3] - p [1] * p [2];
p [9] = p [2] * p [5] - p [3] * p [4];
p [10] = p [4] * p [7] - p [5] * p [6];
p [11] = p [6] * p [1] - p [7] * p [0];
// Смотрим критерий обхода "по" или "против" часовой стрелки четырёхугольника
p [12] = p [8] > 0 && p [9] > 0 && p [10] > 0 && p [11] > 0 || p [8] < 0 && p [9] < 0 && p [10] < 0 && p [11] < 0;
if (p [12])
{
d = ma (ka, kb, ke, kf);
e = ma (ka, kb, kc, kd);
f = ma (kc, kd, ke, kf);
g = ma (ke, kf, kg, kh);
h = ma (kg, kh, ka, kb);
ib [6] = mb (d, e, f) + mb (d, g, h);
}
else ib [6] = 0;
/* 82.1.52.26. Вычислить n-й элемент арифметической прогрессии: a1 = 1, a2 = 3, a3 = 5, a4 = 7, a5 = 9, … . */
a = 1;
for (b = 1; b < ka; b++) a += 2;
ia [15] = a;
/* 83.2.53.27. Просуммировать первые n элементов геометрической прогрессии: a1 = 1, a2 = 2, a3 = 4, a4 = 8, a5 = 16, … (не пользуясь формулой для суммы первых n членов прогрессии). */
a = 1; b = a;
for (c = 1; c < ka; c++) {a *= 2; b += a;}
ia [16] = b;
/* 87.6.57.30. В ходе лечебного голодания масса пациента за 30 дней снизилась с 96 до 70 кг. Было установлено, что ежедневные потери массы пропорциональны массе тела. Вычислить, чему была равна масса пациента через k дней после начала голодания для k = 1, 2, …, 29. */
d = exp (1 / 30. * log (70 / 96.));
e = 96;
for (a = 0; a < ka && a < 30; a++) e *= d;
ib [9] = e;
}
/* * * * * * * * * * * * * * * * * * * * * * * * 2 */
if (af == 3)
{
/* 19.1.5. Вычислить степенную функцию с целым показателем y = x^k, где k - целое число, x != 0. */
ia [4] = a = b = (int) cb;
if (b < 0) b = -b;
if (ca == 0)
ib [0] = 0;
else
{
d = 1;
for (c = 0; c < b; c++) d *= ca;
if (a < 0) d = 1 / d;
ib [0] = d;
}
/* 21.2.7. Дана скорость ракеты при выходе за пределы атмосферы Земли. Составить алгоритм определения того, как будет двигаться ракета после выключения двигателей. (Напомним величины трёх космических скоростей: 7,5 км/с, 11,2 км/с, 16,4 км/с.) */
if (ca < 7.5) ic [1].Format ("7. Ракета упадёт на Землю.");
else if (ca == 7.5) ic [1].Format ("7. Ракета будет двигаться по круговой орбите около Земли.");
else if (ca < 11.2) ic [1].Format ("7. Ракета будет двигаться по эллиптической орбите около Земли.");
else if (ca == 11.2) ic [1].Format ("7. Ракета улетит от Земли по параболе.");
else if (ca < 16.4) ic [1].Format ("7. Ракета будет двигаться по эллипсу вокруг Солнца.");
else if (ca == 16.4) ic [1].Format ("7. Ракета улетит от Солнца по параболе.");
else ic [1].Format ("7. Ракета улетит от Солнца по гиперболе.");
/* 64.2.32.16. Вычислить сумму конечного числа членов гармонического ряда. Суммирование прекращается, когда очередное слагаемое становится меньше epsilon или целая переменная i достигает значения maxint.
1 + 1 / 2 + 1 / 3 + ... + 1 / i + ... . */
d = ca;
if (d <= 0) d = 1;
d = 1 / d;
if (d > 1000000) d = 1000000;
a = (int) d;
d = 0;
for (b = a; b > 0; b--) d += 1. / b;
ib [3] = d;
/* 68.4.36.19. Вычислить сумму квадратов всех целых чисел, попадающих в интервал (ln x, exp x), где x > 1. */
d = ca; // проверка вычислимости границ интервала
if (d <= 0) d = 1;
if (d > 10) d = 10;
e = log (d); // расчёт границ интервала
f = exp (d);
a = (int) e;
b = (int) f;
if (a == e) a++;
if (b == f) b--;
m = 0; // вычисление суммы
for (c = a; c <= b; c++) m += c * c;
ia [12] = m;
/* 68.5.37.20. Вычислить количество точек с целочисленными координатами, попадающих в круг радиуса R (R > 0) с центром в начале координат. */
d = ca;
a = (int) d;
if (a >= 500) d = a = 500; // установка максимального радиуса круга
m = 0;
for (b = -a; b <= a; b++)
for (c = -a; c <= a; c++)
if (b * b + c * c <= d * d) m++;
if (ca < 0) m = 0; // радиус круга - неотрицательное число
ia [13] = m;
/* 84.4.55.28. Для заданного вещественного x и малой величины epsilon (например, epsilon = .000001) вычислить сумму ряда, включив в неё только слагаемые, превышающие epsilon: 1 + x + x^2 / 2! + x^3 / 3! + ... . */
a = 0; // номер члена ряда
d = cb; // ограничение членов ряда epsilon
if (d <= 0) d = 1;
e = 1; // нулевой член ряда
f = 0; // сумма ряда
do {
f += e;
a++;
e *= ca / a;
} while (e >= d);
ib [7] = f;
/* 85.5.56.29. Для заданного натурального N и вещественного x (x > 0) вычислить значение выражения: sqrt (x + sqrt (x + … + sqrt (x))). */
a = (int) cb; // число корней
if (a < 0) a = -a;
if (!a) a = 1;
if (a > 1000) a = 1000;
d = ca; // подкоренное число
if (d < 0) d = -d;
e = sqrt (d);
for (b = 1; b < a; b++) e = sqrt (d + e);
ib [8] = e;
} // конец функции (af = 3)
}
double CP11Doc::ma (int a, int b, int c, int d)
{
int e;
e = (c - a) * (c - a) + (d - b) * (d - b);
if (e < 0) e = 0;
return sqrt (e);
}
double CP11Doc::mb (double a, double b, double c)
{
double d, e;
d = (a + b + c) / 2;
e = d * (d - a) * (d - b) * (d - c);
if (e < 0) e = 0;
return sqrt (e);
}
CP11Doc::na (int a)
{
int b;
b = 0;
while (a)
{
b += a % 10;
a /= 10;
}
return b;
}

Комментарии