A413a

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

a) Найти число команд, имеющих побед больше, чем поражений.

Тесты:

Матрица Число команд Комментарий
3

0 2 2

0 0 1

0 1 0

1 Работает
4

0 2 1 1

0 0 2 2

1 0 0 0

1 0 2 0

2 Работает
2

0 1

1 0

0 Работает

Объяснение переменных:

int n — число команд (размерность квадратной матрицы)

double k = 0 — вспомогательная переменная для метода, описанного ниже (особенности)

int m[n][n] — квадратная матрица, в которую вносится турнирная таблица.

int d = 0- переменная для счёта удоволетроворяющих условию команд

Код: проверить на ideone.

Алгоритм:

  1. Ввод n ( cin >> n ).
  2. Заполнение массива m ( cin >> m[i][j] ).
  3. Подсчет суммы очков команды ( k += m[i][j] ).
  4. Если k делённое на количество игр больше 1 (  k/(n-1) [latex]\in \Re [/latex]  ), d++.
  5. Обнуляем k. Возвращаемся к п.3, пока не будет выполнен цикл
  6. По завершению цикла выводим d.

 Особенности:

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

Если сумма очков команды делится на количество игр и даёт 1, то это значит, что либо победы = поражениям (не подходит по условию) либо это сплошные ничьи (снова победы = проигрышам). Причем, если ответ больше 1, то и побед больше, чем поражений. Если ответ меньше 1, то побед меньше, чем поражений.

Ю5.11

Задача: Задача Иосифа. По кругу располагается  [latex]n[/latex]  человек. Ведущий считает по кругу и выводит («казнит»)  [latex]m[/latex]-го человека*. Круг смыкается, счет возобновляется со следующего после «казнённого»; так продолжается, пока «в живых» не остаётся только 1 человек. Найти номер этого человека, [а так-же для заданного  [latex]n[/latex]  найти такое  [latex]m>1[/latex] , при котором в живых остаётся первый]**.

* — m не может превышать n по условию.

** — вторая часть задачи.

Тесты:   

Ввод Вывод Комментарий
2 1 2 [2] Работает
3 3 2 [не существует] Работает
271 42 121 [69] Работает
271 69 1 [69] Работает

Объяснение переменных:

bool existing - булева переменная для фиксирования существования второй части задачи.

vector <int> a — вектор, по задаче представляет собой нумерацию людей.

unsigned int n, m — переменные, где n и m соответсвуют условию задачи.

int JeosifFunc(a, n, m) — функция, которая выполняет основной алгоритм задачи.

 

 Код: Проверить на ideone.

Алгоритм выполнения описан в комментариях в коде.

 

Особенности:

  1. В коде очень легко запутаться, т.к. нумерация «слотов» вектора начинается с нуля, следовательно везде по коду мы должны это учитывать. Это здорово мешает в понимании кода.
  2. Алгоритм выполнения первой задачи заключен в функцию. Без этого хода нельзя было бы выполнить вторую часть задания методом, представленным выше.
    if( JeosifFunc(a, n, k) == 1 )

Ю12.31

Задача: строка содержит арифметическое выражение, состоящее из целых чисел и знаков операции: [latex]+,-,*,/[/latex]  (без скобок). Проверить корректность выражения (в смысле последовательности чисел и знаков операции)

Тесты: 

Выражение Ответ Комментарий
-1+2-3/4*5 Верно Работает
-1 Верно Работает
-1/-4 Верно Работает
5—4 Верно Работает
1 Верно Работает
54-*3//6 Ошибка Работает. Неправильная последовательность
5/0+42 Ошибка Работает. Деление на ноль
5/ Ошибка Работает. После символа должно следовать число

Объяснение переменных:

string a  — строка для ввода.

bool rightness  — булева переменная для фиксирования ошибочного выражения.

Код:  Проверить на ideone.

Алгоритм выполнения описан в комментариях в коде.

 

Особенности:

  1. Удобно предположить, что изначально выражение верно. И в случае отсутствия ошибок, переменной rightness присваивать ничего не нужно будет.

Итог работы:

Код проверяет правильность выражения (последовательность чисел и знаков) с учётом унарного минуса (но не плюса)*, так-же за ошибку считается деление на ноль. Примеры применения есть в тестах.

* — легко реализовать посредством удаления a[0] == '+' из соответствующих if’ах, но не стал, так как считаю унарный плюс бессмысленным.

Ю4.36

Задача: Гидрологами исследовано течение реки в некотором сечении: произведена серия замеров от одного берега до другого перпендикулярно фарватеру, полученные данные: [latex]{s}_{i}[/latex]  — расстояние от левого берега, м; [latex]{h}_{i}[/latex]  — глубина реки, м; [latex]{v}_{i}[/latex]  — скорость течения, м/с, [latex]i=1,2…,n[/latex] . Каков расход воды в секунду? То есть сколько кубометров воды протекает через сечение в секунду?

Тесты:  (сначала вводятся все данные одного массива, а не поочерёдно)

Ввод Ответ Комментарий
3
[2 4 6] [4 5 5] [3 7 2]
 88 Работает
2
[13 42] [17 18] [3.14 2.71]
1409.85 Работает

Объяснение переменных:

int n - количество замеров

int area = 0 - площадь поперечного сечения (требуется для формулы расхода воды)

int velocity = 0 - cумма скоростей, позже будет делится на количество замеров (тоже для формулы)

double s[n], h[n], v[n]; - массивы с данными о замере

Код: проверить на ideone.

Алгоритм выполнения описан в комментариях в коде.

Используется формула расхода воды:  [latex]Q=Av[/latex]  , где [latex]A[/latex]  — площадь поперечного сечения, а [latex]v[/latex]  — среднее арифметическое скорости течения всех замеров. Метод подсчета площади сечения реки описан по ссылке.

Для понимания метода:

270

 

Первый и последний «замер» на картинке образуют треугольники (относительно берега). Между ними —  прямоугольные трапеции (  [latex]S=\frac { a+b }{ 2 } h[/latex], где [latex]a[/latex], например, линия 2-го замера (по картинке), а  [latex]b[/latex]  линия 3-го замера соответственно, [latex]h[/latex]  — расстояние от 2-го замера до 3-го (нынешнее расстояние от берега отнять прошлое). Суммируем площади фигур — это и будет площадь сечения реки.

Замечание:

Данные должны вводится последовательно относительно удаления от левого берега. Подразумевается, что гидрологи обязательно замеряли всю реку (от левого до правого берегов) минимум 2-мя замерами.

 

Ю3.37

Задача. Численно убедиться в справедливости равенства, для чего для заданного значения аргумента [latex]x[/latex] вычислить левую его часть и разложение, стоящее в правой части, с заданной погрешностью [latex]e[/latex]. Испытать разложение на сходимость при разных значениях аргумента, оценить скорость сходимости, для чего вывести число итераций [latex]n[/latex](слагаемых или сомножителей), необходимых для достижения заданной точности.

[latex]\frac {{e}^{x}-{e}^{-x}}{2} =x+\frac {{x}^{3}}{3!}+\frac {{x}^{5}}{5!} +…+\frac {{x}^{2n-1}}{(2n-1)!} +…[/latex]

x e результат Комментарий
5 0.01 0.002312 Работает
3.14 0.999 0.686728 Работает
4 0 Эквивалентно Работает

Всё просто. Считаем левую часть, считает правую часть циклом. В том же цикле ждём момента когда [latex]le-pr[/latex] будет меньше или равно заданной погрешности.

ideone

Вывод: Задача решена.

Ю3.15

Задача: Сравнить скорость сходимости (число слагаемых для заданной точности [latex]e[/latex]  следующих разложений числа [latex]\pi[/latex]

 

1.   [latex]\pi=4\left(1-\frac {1}{3}+\frac {1}{5}-\frac {1}{7}+\frac {1}{9} -… \right)[/latex]

 

2.   [latex]\pi=3+4\left(\frac {1}{2\cdot 3\cdot 4}-\frac {1}{4\cdot 5\cdot 6}+\frac {1}{6\cdot 7\cdot 8\cdot } -…\right)[/latex]

 

3.   [latex]\pi=\sqrt {6\left(1+\frac {1}{ {2}^{2} } +\frac {1}{ {3}^{2}}+\frac {1}{ {4}^{2}}+… \right) }[/latex]

Число слагаемых (е) Вариант 1 Вариант 2 Вариант 3 Комментарий
1 0.858407 0.025074 0.692103 Работает
2  0.474926 0.00825932  0.40298 Работает
3 0.325074  0.00825932 0.283855 Работает
10  0.099753 0.000185935 0.092231 Работает

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

ideone

Вывод: Второе разложение является самым точным.

A166

Задача: 

Дано натуральное число [latex]n[/latex], действительные числа  [latex]{a}_{1},…,{a}_{n}[/latex] . Получить числа[latex]{b}_{1},…,{b}_{n}[/latex], которые связаны с [latex]{a}_{1},…,{a}_{n}[/latex]  следующим образом:

[latex]{ b }_{ 1 }={ a }_{ 1 },{ \quad b }_{ n }={ a }_{ n },\quad { b }_{ i }=\frac { { a }_{ i+1 }\quad -\quad { a }_{ i } }{ 3 } ,\quad i=2,…,n-1[/latex]

Тесты:                               (числа разделяются «|» для удобного чтения)

Ввод Вывод Комментарий:
3 | 3 | 3 | 3 3 | 0 | 3 Работает.
4 | 3.14 | -2.71 | 42 | 10 3.14 | 14.9033 | -10.6667 | 10 Работает.
1 | 2 | 3 | 4 | 5 2 Работает.
5 | 4 | -3 | 2 | -1 | 0 4 | 1.66667 | -1 | 0.333333 | 0 Работает.

Объяснение переменных:

[latex]n[/latex] — это  [latex]n[/latex]  из условия.

[latex]a1, a2[/latex] — динамические числа, которые меняются с каждым шагом цикла.  [latex]a1[/latex]  — вводится с клавиатуры.  [latex]a2[/latex] — дублируется с [latex]a1[/latex]  посредством шага цикла. Нужны для выполнения условия [latex]{ b }_{ i }=\frac { { a }_{ i+1 }\quad -\quad { a }_{ i } }{ 3 }[/latex]

 

Код:   Проверить на ideone.

Алгоритм выполнения объясняется в комментариях в коде

 

Особенности:

  1. Переменные:
    • int  n<code>;.  <code>int<code> , ибо так требует негласное условие задачи.
    • double a1, a2<code>;.   <code>double<code>  так как в задаче не обговаривалось на каком числовом поле её следует выполнять, то я предпочёл [latex]a1,a2 \in \Re [/latex] .
  2. Цикл for<code> (укажу особенности):
      • (i++, a2 = a1)<code>   - шаг цикла (модификация). Увеличение счётчика на единицу, присвоение [latex]a2[/latex] значение [latex]a1[/latex]

    Сложность этой задачи сводится к понимаю a2 = a1<code>. Цикл выполнит шаг тогда, когда он выполнил задачу своего "тела". Так как на следущее выполнение "тела" [latex]a2[/latex] "не успеет" обновится, то [latex]a2[/latex] становится "предыдущим" элементом

Итог работы:

Код обрабатывает поток данных [latex]n[/latex] раз. Это значит, что лишние числа будут игнорироваться.

А49

Задача: Дано действительное число  [latex]h[/latex] , Выяснить, имеет ли уравнение  [latex]{ ax }^{ 2 }+bx+c=0[/latex]  действительные корни, если:

[latex]a=\sqrt{\frac{\left|\sin{8h}\right|+17}{{(1-\sin{4h}\cos({h}^{2}+18))}^{2}}}[/latex]  ,

[latex]b=1-\sqrt {\frac {3}{3+\left|\tan{a{h}^{2}}-\sin{ah}\right|}}[/latex],

[latex]c=a{ h }^{ 2 }\sin{bh}+b{ h }^{ 3 }\cos{ah}[/latex]  .

Если действительные корни существуют, то найти их. В противном случае ответом должно служить сообщение, что корней нет.

h Корни Комментарий
-10 (-11.8266, 11.7792) Пройден
-7.5 (-7.02349, 6.99523) Пройден
-2 (-1.36947, 1.36885) Пройден
-1 (-0.400785, 0.3912) Пройден
0 0 Пройден (1 корень)
1 корней нет Пройден
2 корней нет Пройден
7.5 корней нет Пройден
10 корней нет Пройден

 

Задача простая. Алгоритм решения такой-же, как и при решении квадратного уравнения.

 

Проверить программу на ideone

Вывод: В тестах взял стандартный набор значений. Программа работает. Интересно заметить, что при любом положительном значении [latex]h[/latex] корней нет.

Ю2.32

Задача:  Из круга какого наименьшего радиуса можно вырезать треугольник со сторонами   [latex]a,b,c[/latex]

Указание: Пусть  [latex]c[/latex]    — большая из сторон треугольника. Если угол [latex]C[/latex] — тупой, сторона совпадает с диаметром круга и его радиус: [latex]r=\frac {C}{2}[/latex] .
В противном случае имеем описанную окружность: [latex]r=\frac {abc}{4\sqrt {p(p-a)(p-b)(p-c)}}[/latex]
где [latex]p=\frac{(a+b+c)}{2}[/latex]

a b c r Комментарий:
6 8 11 5.5 Пройден (Есть тупой угол С)
11 8 6 5.5 Пройден (Есть тупой угол А)
8 11 6 5.5 Пройден (Есть тупой угол B)
5.97 9.55 11.07 5.53894 Пройден (Дробные значения)
3 3 4 2.01246 Пройден (Равнобедренный без тупого угла)
3 3 6 3 Пройден (Равнобедренный с тупым углом)
7 7 7 4.04145 Пройден (Равносторонний)
1 1 20 не треугольник Не пройден (Не треугольник)

До ветвлений:

1. Вычисление каждого угла в получившемся треугольнике через теорему косинусов

2. Вычисление большей стороны треугольника

Алгоритм ветвлений:

Один из углов треугольника  находится в сегменте (90, 180)
Правда Не правда
[latex]r=\frac {C}{2}[/latex] . [latex]r=\frac{abc}{ 4\sqrt{ p(p-a)(p-b)(p-c)} }[/latex]
Вывод

 

Проверить программу на ideone

Вывод: Программа выполняет поставленные задачей условия. Если хоть один угол находится в сегменте (90, 180), то [latex]r=\frac{finding}{2}[/latex]  , где  [latex]finding[/latex]   это большая сторона треугольника (см. 8). В другом случае  [latex]r=\frac{abc}{ 4\sqrt{ p(p-a)(p-b)(p-c)} }[/latex]   . Если треугольник не существует — не выполняется и программа сообщает об этом.

Ю1.16

Задача: в равнобедренном прямоугольном треугольнике известна высота h, опущенная на гипотенузу. Найти стороны треугольника.

h a b c Комментарий
5 7.07107 7.07107 10 Пройдено.
7 9.89949 9.89949 14 Пройдено.
3.53553 5 5 7.07106 Пройдено.

Довольно простая задача в виду того, что прямоугольный равнобедренный треугольник это квадрат с сечением по диагонали. Диагональ [latex]c=a\sqrt { 2 } [/latex],  а

[latex]h=\frac { a\sqrt {2}}{2}[/latex],   т.к. это половина диагонали.

Из этого следует, что      [latex]a=\frac{c}{\sqrt{ 2 }}[/latex],   [latex]a=b[/latex]

 

Алгоритм выполнения задачи:

1. Узнаю [latex]c=2h[/latex]

2. Узнаю    [latex]a=\frac{c}{\sqrt{ 2 }}[/latex],   [latex]a=b[/latex]

 

Вывод: В виду того, что треугольник равнобедренный, задача не вызывает никаких трудностей и легко решаема.

Ю1.6

Задача: Коммерсант, имея стартовый капитал k, занялся бизнесом, который ежемесячно увеличивал капитал на p%. Через сколько лет* он накопит сумму s, достаточную для покупки собственного магазина?

k p s m (месяцы)  Коменнтарий:
0 50 500  — No money — no honey
10 0 500 Это не бизнес
50 50 0 0  Логично, программа работает, вводить частный случай не стал.
1000 5 500 9 Пройден
30 15 500 21 Пройден
30 150 500 4 Пройден
5.556 49.04 193.6 9 Пройден

 

 

Решение выполняется с помощью цикла while, который выполняет циклы пока заданное условие правда (см. 12).

Алгоритм цикла:

  1. Цикл работает, пока сумма сложных процентов меньше, чем сумма.

2. Т.к. процент сложный, то он должен изменяться с каждым циклом. Для этого я ввел вспомогательную переменную v.

где k — капитал, pk — сумма сложных процентов.

  1. Делаем сумму сложных процентов

  1. Добавляем месяцы, пока pk не станет большей или равной s.

Вывод: таким образом код работает независимо от того, какой капитал, какой процент или какая сумма. Не беря во внимание частные случаи, код для своей задачи универсален.

 

Частные случаи:

  1. Когда k = 0. Такая ситуация не имеет логического значения ни в коде, ни в жизни. По этому я её обыграл с помощью if. Код не работает

  2. Когда p = 0. Аналогично первому, логики нет. Код не работает

  3. Когда s = 0. В таком случае, магазин бесплатен.  Код работает

 

* — работал в месяцах, так удобней, ибо месячный процент

 

А вообще, время 5 утра. А я только осознал, что у меня 1.16, а не 1.6. Но пусть будет =)