Условие задачи
Вычислите функцию:
Входные данные
Одно натуральное число [latex] n \; [/latex] [latex](1 \leq n \leq 10^{12}) [/latex].
Выходные данные
Значение [latex] f(n) [/latex], взятое по модулю [latex] 2^{32} [/latex].
Continue reading
Условие задачи
Вычислите функцию:
Входные данные
Одно натуральное число [latex] n \; [/latex] [latex](1 \leq n \leq 10^{12}) [/latex].
Выходные данные
Значение [latex] f(n) [/latex], взятое по модулю [latex] 2^{32} [/latex].
Continue reading
Дана функция, аргументы которой – неотрицательные целые числа [latex]m[/latex] и [latex]n[/latex] [latex](m ≤ n)[/latex]:
Составить алгоритм, вычисляющий значение функции.
Два целых неотрицательных числа [latex]n[/latex] и [latex]m[/latex] [latex](0 ≤ m, n ≤ 20)[/latex].
Выведите искомое значение заданной функции [latex]f(m, n)[/latex].
# | Входные данные | Выходные данные |
---|---|---|
1 | 4 2 | 6 |
2 | 7 7 | 1 |
3 | 12 0 | 1 |
4 | 15 5 | 3003 |
5 | 10 6 | 210 |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> using namespace std; int f( int m, int n) { // функция с её аргументами if (m == 0 || m == n ) return 1; if (m < n) return f(m - 1, n - 1) + f(m, n - 1); } int main() { int n, m, d; cin >> n >> m; d = f(m, n); //вызов функции cout << d; return 0; } |
Для того, чтобы решить задачу, нам необходимо составить алгоритм, который будет вычислять значение заданной функции в зависимости от значения её аргументов. Для этого создадим специальную функцию [latex]f[/latex].
Строки 4 — 6 кода составляют тело функции. Программа выбирает, какую операцию ей нужно выполнить, в зависимости от определенного условия:
Далее в главной функции main() мы вызываем нашу функцию [latex]f[/latex] с помощью новой переменной [latex]d[/latex] и выводим результат.
Ссылка на e-olymp
Ссылка на ideone
Дана функция, аргументы которой — произвольные натуральные числа
[latex]f(M,N)=\begin{cases} f(M-N,N), & \text{ npu } M>N \\ N, & \text{ npu } M=N \\ f(N-M,M) & \text{ npu } N>M \end{cases}[/latex]Составить алгоритм (написать программу), вычисляющий значение функции.
Два натуральных числа [latex]n[/latex] и [latex]m[/latex] [latex](1 \le n, m \le 10^{18})[/latex].
Искомое значение функции.
Входные данные | Выходные данные |
[latex]6[/latex] [latex]3[/latex] | [latex]3[/latex] |
[latex]12[/latex] [latex]12[/latex] | [latex]12[/latex] |
[latex]126[/latex] [latex]98[/latex] | [latex]98[/latex] |
[latex]10329[/latex] [latex]1501[/latex] | [latex]1501[/latex] |
[latex]1008359[/latex] [latex]15113[/latex] | [latex]15113[/latex] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> using namespace std; unsigned long long f(unsigned long long n, unsigned long long m) { if (n % m == 0) return m; if (m % n == 0) return n; if (m > n) f(m % n, n); else f(n % m , m); } int main() { unsigned long long n, m, t; cin >> m >> n; t = f(m, n); cout << t; return 0; } |
Для решения задачи напишем функцию [latex]f[/latex]. Именно эта функция и будет считать искомое значение. Из условия задачи видим, что для решения потребуется рекурсия. Для этого, если остаток от деления одного натурального числа на другое не равен нулю, то мы снова возращаемся в функцию (в зависимости от того,
что больше [latex]m[/latex] или [latex]n[/latex]). Это будет продолжаться до тех пор, пока остаток от деления одного натурального числа на другое не будет равен нулю (как только $n\mod m = 0$ или $m\mod n = 0$, то функция возращает в переменную [latex]t[/latex] искомое значение). Задача решена.
Условие задачи на e-olymp
Код решения на ideone.com
Задана точка с координатами [latex]x[/latex] и [latex]y[/latex]. Определить, в какой координатной четверти она расположена.
В единственной строке через пробел заданы [latex]2[/latex] вещественных числа — координаты точки, значения координат по модулю не превышают [latex]100[/latex].
Единственное число — номер соответствующей четверти, либо [latex]0[/latex] , если однозначно определить четверть невозможно.
Входные данные | Выходные данные | |
[latex]x[/latex] | [latex]y[/latex] | Четверть |
12 | 31 | 1 |
-10 | 18 | 2 |
-15 | -25 | 3 |
13 | -13 | 4 |
0 | 0 | 0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> #include <cmath> using namespace std; int main() { float x, y; cin >> x >> y; if (x > 0 && y > 0) { cout << "1" << endl; } else if (x < 0 && y > 0) { cout << "2" << endl; } else if (x < 0 && y < 0) { cout << "3" << endl; } else if (x > 0 && y < 0) { cout << "4" << endl; } else { cout << "0" << endl; } return 0; } |
Четверти координатной плоскости
В прямоугольной системе координат на плоскости выделяют 4 четверти: 1, 2, 3, 4.
1-й четветри соответствуют точки, имеющие обе ([latex]x[/latex] и [latex]y[/latex]) положительные координаты.
2-ая четверть: [latex]x \lt 0[/latex], [latex]y \gt 0[/latex].
3-ая четверть: [latex]x \lt 0[/latex], [latex]y \lt 0[/latex].
4-ая четверть: [latex]x \gt 0[/latex], [latex]y \lt 0[/latex].
Точка с координатами ([latex]0[/latex];[latex]0[/latex]), находится в начале координат.
Если точка лежит на оси [latex]«Oy»[/latex], то её абсцисса равна [latex]0[/latex].
Если точка лежит на оси [latex]«Ox»[/latex], то её ордината равна [latex]0[/latex].
Дано 10 булевых переменных [latex] x_{1},\:x_{2},\:x_{3} ,\:x_{4},\:x_{5},\:x_{6},\:x_{7},\:x_{8},\:x_{9},\:x_{10} [/latex]. Вычислите количество пар и троек, у которых хотя бы одна переменная установлена в [latex]1[/latex]. Установим [latex]f( x_{1},\:x_{2},\:x_{3} ,\:x_{4},\:x_{5},\:x_{6},\:x_{7},\:x_{8},\:x_{9},\:x_{10}) = 1[/latex] если это количество нечетно и [latex]f( x_{1},\:x_{2},\:x_{3} ,\:x_{4},\:x_{5},\:x_{6},\:x_{7},\:x_{8},\:x_{9},\:x_{10}) = 0[/latex] если количество четно.
Рассмотрим явную формулу, которая реализует функцию [latex]f( x_{1},\:x_{2},\:x_{3} ,\:x_{4},\:x_{5},\:x_{6},\:x_{7},\:x_{8},\:x_{9},\:x_{10}):[/latex]
[latex]f( x_{1},\:x_{2},\:x_{3} ,\:x_{4},\:x_{5},\:x_{6},\:x_{7},\:x_{8},\:x_{9},\:x_{10}) = [/latex] [latex]
\left( x_{1}\vee x_{2} \right) \oplus \left( x_{1}\vee x_{3} \right) \oplus \left( x_{1}\vee x_{4} \right)\oplus \left( x_{1}\vee x_{5} \right)
\oplus \left( x_{1}\vee x_{6} \right) \oplus \left( x_{1}\vee x_{7} \right) \oplus \left( x_{1}\vee x_{8} \right) \\
\oplus \left( x_{1}\vee x_{9} \right) \oplus \left( x_{1}\vee x_{10} \right) \oplus \left( x_{2}\vee x_{3} \right)
\oplus \left( x_{2}\vee x_{4} \right) \oplus \left( x_{2}\vee x_{5} \right) \oplus \left( x_{2}\vee x_{6} \right) \\
\oplus \left( x_{2}\vee x_{7} \right) \oplus \left( x_{2}\vee x_{8} \right) \oplus \left( x_{2}\vee x_{9} \right)
\oplus \left( x_{2}\vee x_{10} \right) \oplus \left( x_{3}\vee x_{4} \right) \oplus \left( x_{3}\vee x_{5} \right) \\
\oplus \left( x_{3}\vee x_{6} \right) \oplus \left( x_{3}\vee x_{7} \right) \oplus \left( x_{3}\vee x_{8} \right)
\oplus \left( x_{3}\vee x_{9} \right) \oplus \left( x_{3}\vee x_{10} \right) \oplus \left( x_{4}\vee x_{5} \right) \\
\oplus \left( x_{4}\vee x_{6} \right) \oplus \left( x_{4}\vee x_{7} \right) \oplus \left( x_{4}\vee x_{8} \right)
\oplus \left( x_{4}\vee x_{9} \right) \oplus \left( x_{4}\vee x_{10} \right) \oplus \left( x_{5}\vee x_{6} \right) \\
\oplus \left( x_{5}\vee x_{7} \right) \oplus \left( x_{5}\vee x_{8} \right) \oplus \left( x_{5}\vee x_{9} \right)
\oplus \left( x_{5}\vee x_{10} \right) \oplus \left( x_{6}\vee x_{7} \right) \oplus \left( x_{6}\vee x_{8} \right) \\
\oplus \left( x_{6}\vee x_{9} \right) \oplus \left( x_{6}\vee x_{10} \right) \oplus \left( x_{7}\vee x_{8} \right)
\oplus \left( x_{7}\vee x_{9} \right) \oplus \left( x_{7}\vee x_{10} \right) \oplus \left( x_{8}\vee x_{9} \right) \\
\oplus \left( x_{8}\vee x_{10} \right) \oplus \left( x_{9}\vee x_{10} \right) \oplus \left( x_{1}\vee x_{2}\vee x_{3} \right)
\oplus \left( x_{1}\vee x_{2}\vee x_{4} \right) \oplus \left( x_{1}\vee x_{2}\vee x_{5} \right) \\ \oplus \left( x_{1}\vee x_{2}\vee x_{6} \right)
\oplus \left( x_{1}\vee x_{2}\vee x_{7} \right) \oplus \left( x_{1}\vee x_{2}\vee x_{8} \right) \oplus \left( x_{1}\vee x_{2}\vee x_{9} \right)
\oplus \\ \left( x_{1}\vee x_{2}\vee x_{10} \right) \oplus \left( x_{1}\vee x_{3}\vee x_{4} \right) \oplus \left( x_{1}\vee x_{3}\vee x_{5} \right)
\oplus \left( x_{1}\vee x_{3}\vee x_{6} \right) \oplus \\ \left( x_{1}\vee x_{3}\vee x_{7} \right) \oplus \left( x_{1}\vee x_{3}\vee x_{8} \right)
\oplus \left( x_{1}\vee x_{3}\vee x_{9} \right) \oplus \left( x_{1}\vee x_{3}\vee x_{10} \right) \oplus \left( x_{1}\vee x_{4}\vee x_{5} \right) \\
\oplus \left( x_{1}\vee x_{4}\vee x_{6} \right) \oplus \left( x_{1}\vee x_{4}\vee x_{7} \right) \oplus \left( x_{1}\vee x_{4}\vee x_{8} \right)
\oplus \left( x_{1}\vee x_{4}\vee x_{9} \right) \oplus \\ \left( x_{1}\vee x_{4}\vee x_{10} \right) \oplus \left( x_{1}\vee x_{5}\vee x_{6} \right)
\oplus \left( x_{1}\vee x_{5}\vee x_{7} \right) \oplus \left( x_{1}\vee x_{5}\vee x_{8} \right) \oplus \left( x_{1}\vee x_{5}\vee x_{9} \right) \\
\oplus \left( x_{1}\vee x_{5}\vee x_{10} \right) \oplus \left( x_{1}\vee x_{6}\vee x_{7} \right) \oplus \left( x_{1}\vee x_{6}\vee x_{8} \right)
\oplus \left( x_{1}\vee x_{6}\vee x_{9} \right) \\ \oplus \left( x_{1}\vee x_{6}\vee x_{10} \right) \oplus \left( x_{1}\vee x_{7}\vee x_{8} \right)
\oplus \left( x_{1}\vee x_{7}\vee x_{9} \right) \oplus \left( x_{1}\vee x_{7}\vee x_{10} \right) \oplus \\ \left( x_{1}\vee x_{8}\vee x_{9} \right)
\oplus \left( x_{1}\vee x_{8}\vee x_{10} \right) \oplus \left( x_{1}\vee x_{9}\vee x_{10} \right) \oplus \left( x_{2}\vee x_{3}\vee x_{4} \right)
\oplus \left( x_{2}\vee x_{3}\vee x_{5} \right) \\ \oplus \left( x_{2}\vee x_{3}\vee x_{6} \right) \oplus \left( x_{2}\vee x_{3}\vee x_{7} \right)
\oplus \left( x_{2}\vee x_{3}\vee x_{8} \right) \oplus \left( x_{2}\vee x_{3}\vee x_{9} \right) \oplus \\ \left( x_{2}\vee x_{3}\vee x_{10} \right)
\oplus \left( x_{2}\vee x_{4}\vee x_{5} \right) \oplus \left( x_{2}\vee x_{4}\vee x_{6} \right) \oplus \left( x_{2}\vee x_{4}\vee x_{7} \right)
\oplus \left( x_{2}\vee x_{4}\vee x_{8} \right) \\ \oplus \left( x_{2}\vee x_{4}\vee x_{9} \right) \oplus \left( x_{2}\vee x_{4}\vee x_{10} \right)
\oplus \left( x_{2}\vee x_{4}\vee x_{6} \right) \oplus \left( x_{2}\vee x_{5}\vee x_{6} \right) \oplus \left( x_{2}\vee x_{5}\vee x_{7} \right) \\
\oplus \left( x_{2}\vee x_{5}\vee x_{8} \right) \oplus \left( x_{2}\vee x_{5}\vee x_{9} \right) \oplus \left( x_{2}\vee x_{5}\vee x_{10} \right)
\oplus \left( x_{2}\vee x_{6}\vee x_{7} \right) \oplus \left( x_{2}\vee x_{6}\vee x_{8} \right) \\ \oplus \left( x_{2}\vee x_{6}\vee x_{9} \right)
\oplus \left( x_{2}\vee x_{6}\vee x_{10} \right) \oplus \left( x_{2}\vee x_{7}\vee x_{8} \right) \oplus \left( x_{2}\vee x_{7}\vee x_{9} \right)
\oplus \left( x_{2}\vee x_{7}\vee x_{10} \right) \\ \oplus \left( x_{2}\vee x_{8}\vee x_{9} \right) \oplus \left( x_{2}\vee x_{8}\vee x_{10} \right)
\oplus \left( x_{2}\vee x_{9}\vee x_{10} \right) \oplus \left( x_{3}\vee x_{4}\vee x_{5} \right) \oplus \left( x_{3}\vee x_{4}\vee x_{6} \right) \\
\oplus \left( x_{3}\vee x_{4}\vee x_{7} \right) \oplus \left( x_{3}\vee x_{4}\vee x_{8} \right) \oplus \left( x_{3}\vee x_{4}\vee x_{9} \right)
\oplus \left( x_{3}\vee x_{4}\vee x_{10} \right) \oplus \left( x_{3}\vee x_{5}\vee x_{6} \right) \\ \oplus \left( x_{3}\vee x_{5}\vee x_{7} \right)
\oplus \left( x_{3}\vee x_{5}\vee x_{8} \right) \oplus \left( x_{3}\vee x_{5}\vee x_{9} \right) \oplus \left( x_{3}\vee x_{5}\vee x_{10} \right)
\oplus \left( x_{3}\vee x_{6}\vee x_{7} \right) \\ \oplus \left( x_{3}\vee x_{6}\vee x_{8} \right) \oplus \left( x_{3}\vee x_{6}\vee x_{9} \right)
\oplus \left( x_{3}\vee x_{6}\vee x_{10} \right) \oplus \left( x_{3}\vee x_{7}\vee x_{8} \right) \\ \oplus \left( x_{3}\vee x_{7}\vee x_{9} \right)
\oplus \left( x_{3}\vee x_{7}\vee x_{10} \right) \oplus \left( x_{3}\vee x_{8}\vee x_{9} \right) \oplus \left( x_{3}\vee x_{8}\vee x_{10} \right)
\oplus \left( x_{3}\vee x_{9}\vee x_{10} \right) \\ \oplus \left( x_{4}\vee x_{5}\vee x_{6} \right) \oplus \left( x_{4}\vee x_{5}\vee x_{7} \right)
\oplus \left( x_{4}\vee x_{5}\vee x_{8} \right) \oplus \left( x_{4}\vee x_{5}\vee x_{9} \right) \oplus \left( x_{4}\vee x_{5}\vee x_{10} \right) \\
\oplus \left( x_{4}\vee x_{6}\vee x_{7} \right) \oplus \left( x_{4}\vee x_{6}\vee x_{8} \right) \oplus \left( x_{4}\vee x_{6}\vee x_{9} \right)
\oplus \left( x_{4}\vee x_{6}\vee x_{10} \right) \oplus \left( x_{4}\vee x_{7}\vee x_{8} \right) \\ \oplus \left( x_{4}\vee x_{7}\vee x_{9} \right)
\oplus \left( x_{4}\vee x_{7}\vee x_{10} \right) \oplus \left( x_{4}\vee x_{8}\vee x_{9} \right) \oplus \left( x_{4}\vee x_{8}\vee x_{10} \right) \\
\oplus \left( x_{4}\vee x_{9}\vee x_{10} \right) \oplus \left( x_{5}\vee x_{6}\vee x_{7} \right) \oplus \left( x_{5}\vee x_{6}\vee x_{8} \right)
\oplus \left( x_{5}\vee x_{6}\vee x_{9} \right) \oplus \left( x_{5}\vee x_{6}\vee x_{10} \right) \\ \oplus \left( x_{5}\vee x_{7}\vee x_{8} \right)
\oplus \left( x_{5}\vee x_{7}\vee x_{9} \right) \oplus \left( x_{5}\vee x_{7}\vee x_{10} \right) \oplus \left( x_{5}\vee x_{8}\vee x_{9} \right)
\oplus \left( x_{5}\vee x_{8}\vee x_{10} \right) \\ \oplus \left( x_{5}\vee x_{9}\vee x_{10} \right) \oplus \left( x_{6}\vee x_{7}\vee x_{8} \right)
\oplus \left( x_{6}\vee x_{7}\vee x_{9} \right) \oplus \left( x_{6}\vee x_{7}\vee x_{10} \right) \oplus \left( x_{6}\vee x_{8}\vee x_{9} \right) \\
\oplus \left( x_{6}\vee x_{8}\vee x_{10} \right) \oplus \left( x_{6}\vee x_{8}\vee x_{9} \right) \oplus \left( x_{6}\vee x_{8}\vee x_{10} \right)
\oplus \left( x_{6}\vee x_{9}\vee x_{10} \right) \\ \oplus \left( x_{7}\vee x_{8}\vee x_{9} \right) \oplus \left( x_{7}\vee x_{8}\vee x_{10} \right)
\oplus \left( x_{7}\vee x_{9}\vee x_{10} \right) \oplus \left( x_{8}\vee x_{9}\vee x_{10} \right) \\
[/latex]
Содержит [latex]10[/latex] чисел [latex] x_{1},\ x_{2},\ x_{3} ,\ x_{4},\ x_{5},\ x_{6},\ x_{7},\ x_{8},\ x_{9},\ x_{10} [/latex]. Каждое из них равно [latex]0[/latex] или [latex]1[/latex].
Вывести единственное значение [latex]f( x_{1}, \ x_{2},\ x_{3} ,\ x_{4},\ x_{5},\ x_{6},\ x_{7},\ x_{8},\ x_{9},\ x_{10}).[/latex]
Входные данные | Выходные данные |
---|---|
1 0 0 1 0 0 1 0 0 1 | 0 |
0 0 0 0 0 0 0 0 0 0 | 0 |
1 1 1 1 1 1 1 1 1 1 | 1 |
1 1 1 1 1 0 0 0 0 0 | 1 |
1 0 1 0 1 0 1 0 1 0 | 1 |
1 2 3 4 5 6 7 8 9 |
#include <iostream> using namespace std; int main() { bool x1, x2, x3, x4, x5, x6, x7, x8, x9, x10; cin >> x1 >> x2 >> x3 >> x4 >> x5 >> x6 >> x7 >> x8 >> x9 >> x10; bool y= (x1||x2)^(x1||x3)^(x1||x4)^(x1||x5)^(x1||x6)^(x1||x7)^(x1||x8)^(x1||x9)^(x1||x10)^(x2||x3)^(x2||x4)^(x2||x5)^(x2||x6)^(x2||x7)^(x2||x8)^(x2||x9)^(x2||x10)^(x3||x4)^(x3||x5)^(x3||x6)^(x3||x7)^(x3||x8)^(x3||x9)^(x3||x10)^(x4||x5)^(x4||x6)^(x4||x7)^(x4||x8)^(x4||x9)^(x4||x10)^(x5||x6)^(x5||x7)^(x5||x8)^(x5||x9)^(x5||x10)^(x6||x7)^(x6||x8)^(x6||x9)^(x6||x10)^(x7||x8)^(x7||x9)^(x7||x10)^(x8||x9)^(x8||x10)^(x9||x10)^(x1||x2||x3)^(x1||x2||x4)^(x1||x2||x5)^(x1||x2||x6)^(x1||x2||x7)^(x1||x2||x8)^(x1||x2||x9)^(x1||x2||x10)^(x1||x3||x4)^(x1||x3||x5)^(x1||x3||x6)^(x1||x3||x7)^(x1||x3||x8)^(x1||x3||x9)^(x1||x3||x10)^(x1||x4||x5)^(x1||x4||x6)^(x1||x4||x7)^(x1||x4||x8)^(x1||x4||x9)^(x1||x4||x10)^(x1||x5||x6)^(x1||x5||x7)^(x1||x5||x8)^(x1||x5||x9)^(x1||x5||x10)^(x1||x6||x7)^(x1||x6||x8)^(x1||x6||x9)^(x1||x6||x10)^(x1||x7||x8)^(x1||x7||x9)^(x1||x7||x10)^(x1||x8||x9)^(x1||x8||x10)^(x1||x9||x10)^(x2||x3||x4)^(x2||x3||x5)^(x2||x3||x6)^(x2||x3||x7)^(x2||x3||x8)^(x2||x3||x9)^(x2||x3||x10)^(x2||x4||x5)^(x2||x4||x6)^(x2||x4||x7)^(x2||x4||x8)^(x2||x4||x9)^(x2||x4||x10)^(x2||x5||x6)^(x2||x5||x7)^(x2||x5||x8)^(x2||x5||x9)^(x2||x5||x10)^(x2||x6||x7)^(x2||x6||x8)^(x2||x6||x9)^(x2||x6||x10)^(x2||x7||x8)^(x2||x7||x9)^(x2||x7||x10)^(x2||x8||x9)^(x2||x8||x10)^(x2||x9||x10)^(x3||x4||x5)^(x3||x4||x6)^(x3||x4||x7)^(x3||x4||x8)^(x3||x4||x9)^(x3||x4||x10)^(x3||x5||x6)^(x3||x5||x7)^(x3||x5||x8)^(x3||x5||x9)^(x3||x5||x10)^(x3||x6||x7)^(x3||x6||x8)^(x3||x6||x9)^(x3||x6||x10)^(x3||x7||x8)^(x3||x7||x9)^(x3||x7||x10)^(x3||x8||x9)^(x3||x8||x10)^(x3||x9||x10)^(x4||x5||x6)^(x4||x5||x7)^(x4||x5||x8)^(x4||x5||x9)^(x4||x5||x10)^(x4||x6||x7)^(x4||x6||x8)^(x4||x6||x9)^(x4||x6||x10)^(x4||x7||x8)^(x4||x7||x9)^(x4||x7||x10)^(x4||x8||x9)^(x4||x8||x10)^(x4||x9||x10)^(x5||x6||x7)^(x5||x6||x8)^(x5||x6||x9)^(x5||x6||x10)^(x5||x7||x8)^(x5||x7||x9)^(x5||x7||x10)^(x5||x8||x9)^(x5||x8||x10)^(x5||x9||x10)^(x6||x7||x8)^(x6||x7||x9)^(x6||x7||x10)^(x6||x8||x9)^(x6||x8||x10)^(x6||x9||x10)^(x7||x8||x9)^(x7||x8||x10)^(x7||x9||x10)^(x8||x9||x10); cout << y; return 0; } |
Рассмотрим все возможные пары и тройки разных переменных из этих десяти (всего существует [latex]45[/latex] пар и [latex]120[/latex] троек). Данная формула реализует функцию [latex]f( x_{1},\ x_{2},\ x_{3} ,\ x_{4},\ x_{5},\ x_{6},\ x_{7},\ x_{8},\ x_{9},\ x_{10}) [/latex]. В указанной формуле бинарные операции обозначаются «[latex]\vee[/latex]» и «[latex]\oplus[/latex]», где «[latex]\vee[/latex]» — логическое или , а «[latex]\oplus[/latex]» — исключающее или
Задача с сайта e-olymp.com.
Имеется строка [latex]s[/latex]. Разрешается взять два любых одинаковых соседних символа и удалить их из строки. Эту операцию можно производить пока имеется возможность. Сначала Вы можете выбрать любое количество символов в строке и удалить их. Определить наименьшее количество символов, которое Вы можете удалить сначала так, чтобы затем выполняя разрешенную операцию, получить пустую строку.
Содержит строку [latex]s[/latex] ([latex]1 ≤[/latex] длина[latex]\left( s \right) [/latex] [latex]≤ 100)[/latex].
Вывести наименьшее количество символов, которое следует удалить сначала.
№ | Входные данные | Выходные данные |
1 | abbcddka | 2 |
2 | ABBA | 0 |
3 | abcde | 5 |
4 | abbac | 1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <iostream> #include <string> using namespace std; int **answers; string s; int calculate(int l, int r){ if(l > r) return 0; //Если индекс левой границы отрезка больше индекса правой. if(answers[l][r] == -1){ //Если ответ для данного отрезка ещё не известен, находим его. answers[l][r] = s.size(); if(s[l] == s[r]) answers[l][r] = min(answers[l][r], calculate(l+1, r-1)); for(int i = l; i < r; ++i){ answers[l][r] = min(answers[l][r], calculate(l, i) + calculate(i+1, r)); } } return answers[l][r]; } int main() { getline(cin, s); //Ввод строки. answers = new int*[s.size()]; for(int i = 0; i < s.size(); ++i){ answers[i] = new int[s.size()]; } //Заполнение массива начальными значениями. for(int i = 0; i < s.size(); ++i){ for(int j = 0; j <= s.size(); ++j){ if(i == j) answers[i][j] = 1; else answers[i][j] = -1; } } //Вывод ответа. cout<<calculate(0, s.size()-1); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import java.util.*; class Main { static int[][] answers; static String s; static int calculate(int l, int r){ if(l > r) return 0; //Если индекс левой границы отрезка больше индекса правой. if(answers[l][r] == -1){ //Если ответ для данного отрезка ещё не известен, находим его. answers[l][r] = s.length(); if(s.charAt(l) == s.charAt(r)) answers[l][r] = Math.min(answers[l][r], calculate(l+1, r-1)); for(int i = l; i < r; ++i){ answers[l][r] = Math.min(answers[l][r], calculate(l, i) + calculate(i+1, r)); } } return answers[l][r]; } public static void main (String[] args) throws java.lang.Exception { Scanner in = new Scanner(System.in); s = in.nextLine(); //Ввод строки. answers = new int[s.length()][s.length()]; //Заполнение массива начальными значениями. for(int i = 0; i < s.length(); ++i){ for(int j = 0; j < s.length(); ++j){ if(i == j) answers[i][j] = 1; else answers[i][j] = -1; } } //Вывод ответа. System.out.print(calculate(0, s.length()-1)); } } |
Идея решения состоит в том, чтобы разбить строку на меньшие по длине подстроки и найти ответ на задачу для каждой из них. Для хранения строки используется переменная s, а ответы на подзадачи содержатся в двумерном массиве целых чисел answers. В answers[i][j] находится ответ для подстроки с i-ого по j-й символ включительно. В функции main сначала вводится строка s. Далее ширина и глубина массива answers устанавливаются равными длине s. После этого он заполняется начальными значениями. Значение [latex]-1[/latex] означает, что ответ для этой ячейки ещё не был найден. Однако очевидно, что если строка состоит ровно из одного символа, согласно условию задачи, его придётся удалить, значит, главную диагональ можно сразу заполнить единицами. Затем происходит вызов рекурсивной функции calculate, принимающей индексы левой и правой границ целевой подстроки. Первый раз она вызывается для всей строки от первого до последнего символа. Работает эта функция следующим образом: если индекс левой границы отрезка больше индекса правой, что, в случае данной задачи, не имеет смысла, она возвращает ноль. Иначе она возвращает ответ на задачу для данной подстроки, а если этого не делалось ранее, то предварительно находит его. Происходит это так: сначала значение ответа устанавливается равным длине подстроки, поскольку в худшем случае необходимо будет удалить её всю целиком. Если символы на концах подстроки одинаковые, они, как сказано в условии, будут удалены в дальнейшем, потому нужно рассматривать минимум из текущего значения ответа и ответа для подстроки без крайних символов. Однако может оказаться, что выгоднее удалить символы из каких-то двух меньших подстрок, потому далее в цикле рассматриваются все возможные комбинации двух подстрок, из которых можно составить конкатенацией текущую. В итоге получаем ответ на задачу для данной подстроки.
Код на ideone.com. (C++)
Код на ideone.com. (Java)
Засчитанное решение на e-olymp.
Обозначим через [latex]a \cdot b[/latex] конкатенацию строк [latex]a[/latex] и [latex]b[/latex].
Например, если [latex]a =[/latex]«abc» и [latex]b =[/latex]«def» то [latex]a \cdot b =[/latex]«abcdef».
Если считать конкатенацию строк умножением, то можно определить операцию возведения в степень следующим образом:
[latex]a^{0} =[/latex]«» (пустая строка)
[latex]a^{n+1} = a \cdot a^{n}[/latex]
По заданной строке [latex]s[/latex] необходимо найти наибольшее значение [latex]n[/latex], для которого [latex]s = a^{n}[/latex] для некоторой строки [latex]a[/latex].
Каждый тест состоит из одной строки [latex]s[/latex], содержащей печатные (отображаемые) символы. Строка [latex]s[/latex] содержит не менее одного и не более миллиона символов.
Для каждой входной строки [latex]s[/latex] вывести в отдельной строке наибольшее значение [latex]n[/latex], для которого [latex]s[/latex] = [latex]a^{n}[/latex] для некоторой строки [latex]a[/latex].
Входные данные | Выходные данные |
---|---|
abcabc gcdgcd gcgcgc gggggg hhhh |
2 2 3 6 4 |
BbbbBbbbBbbb dogdogdog aaaaaaaa cstring |
3 3 8 1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <iostream> #include <cstring> using namespace std; unsigned int cstringpow(const char *s) { unsigned int answer = 1; const unsigned int size = strlen(s); for (unsigned int i = 1; i < size/2+1; ++i) { /* Ищем предполагаемую степень для ответа, которая обязательно является делителем длины строки. */ if (size % i == 0) { bool not_broken = 1; //предполагаем, что выбранная степень строки максимальна for (int j = 0; j < size-i; j += i) { //сравниваем блоки строки if (strncmp(s+j, s+j+i, i) != 0) { not_broken = 0; break; } } if (not_broken) { //Если предполагаемая степень строки оказалась верной, возвращаем её. answer = size/i; break; } } } return answer; } int main() { char s[1000010]; //Выделяем память для строк while (cin >> s) cout << cstringpow(s) << endl; return 0; } |
Из условия следует, что степень строки определяется максимальным числом одинаковых подстрок. В таком случае степень строки является одним из делителей длины этой строки, и очевидно, что максимальная степень строки будет обратно пропорциональна максимальной длине подстроки.
Для решения поставленной задачи используем функцию
cstringpow, которая в качестве аргумента принимает строку, и возвращает её степень. Реализуем эту функцию следующим образом: вначале ищем делители значения переменной
size (с использованием счётчика
i в цикле), в которую было предварительно была сохранена длина строки, полученная функцией
strlen. Числа, которые будут получатся из выражения
size/i, будут предполагаемой максимальной степенью строки. Естественно, они будут находится в порядке убывания.
Найденные счётчиком делители будут представлять из себя длины подстрок, на которые можно полностью разбить данную строку. Затем, используя функцию
strncmp, сравниваем каждую подстроку. В случае, если какие-то из подстрок не совпали, то предположенная максимальная степень строки не является верной, и необходимо искать следующую. Иначе (если несовпадающих подстрок не найдено, то) значение выражения
size/i будет ответом на поставленную задачу. В крайнем случае, необходимое разбиение строки не будет найдено, и тогда совокупностью одинаковых подстрок будет сама строка, а следовательно её степень равна [latex]1[/latex].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#include <iostream> #include <string> using namespace std; unsigned int stringpow(const string &s) { unsigned int answer = 1; const unsigned int size = s.size(); for (unsigned int i = 1; i < size/2+1; ++i) { /* Ищем предполагаемую степень для ответа, которая обязательно является делителем длины строки. */ if (size % i == 0) { bool not_broken = 1; //предполагаем, что выбранная степень строки максимальна for (int j = 0; j < size-i; j += i) { //сравниваем блоки строки if (s.compare(j, i, s, j+i, i) != 0) { not_broken = 0; break; } } if (not_broken) { //Если предполагаемая степень строки оказалась верной, возвращаем её. answer = size/i; break; } } } return answer; } int main() { string s; //Выделяем переменную класса "строка" while (cin >> s) cout << stringpow(s) << endl; return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
import java.util.*; import java.io.*; public class Main { public static int stringpow(String s) { int answer = 1; int size = s.length(); for(int i = 1; i < size/2+1; ++i) { /* Ищем предполагаемую степень для ответа, которая обязательно является делителем длины строки. */ if (size % i == 0) { boolean not_broken = true; //предполагаем, что выбранная степень строки максимальна String current = s.substring(0, i); for(int j = 0; j < size-i; j += i) { //сравниваем блоки строки if (!(current.equals(s.substring(j+i, j+2*i)))) { not_broken = false; break; } } if (not_broken) { answer = size/i; break; } } } return answer; } public static void main (String[] args) throws java.lang.Exception { Scanner in = new Scanner(System.in); PrintWriter out = new PrintWriter(System.out); String S; //Выделяем переменную класса "строка" while(in.hasNextLine()) { S = in.nextLine(); out.println(stringpow(S)); } out.flush(); } } |
Решение задачи с использованием класса string аналогично. Единственное отличие — замена функций strlen и strncmp, предназначенных для работы с c-string, на эквивалентные им методы класса string size и compare.
В черный ящик кладутся листки с написанными на них числами. На каждом листке — ровно одно целое число. Иногда некоторые листки исчезают из ящика. После каждого события (когда в ящик положили листок, или когда из ящика исчез листок), нужно вывести число, которое встречается чаще всего на листках, находящихся в данный момент в ящике. Если таких чисел несколько, выведите наименьшее.
Первая строка содержит количество событий [latex]n[/latex] [latex]\left(1 \le n \le 2 \times 10^{5} \right)[/latex]. Каждая из следующих n строк содержит описание одного события:
Вывести в точности [latex]n[/latex] строк — по одной для каждого события. Каждая строка должна содержать одно число — ответ к задаче. Если после какого-то события ящик оказался пуст, следует вывести [latex]0[/latex].
Входные данные | Выходные данные |
---|---|
3 + 1 — 1 + 2 |
1 0 2 |
6 + 1 + 1000000 — 1 + 4 + 4 — 1000000 |
1 1 1000000 4 4 4 |
8 + 71 + 91 + 99 + 71 — 71 — 91 — 71 — 99 |
71 71 71 71 71 71 99 0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
#include <iostream> using namespace std; template <class POINTER_TYPE, class TYPE> class segment_tree { TYPE *SegmentTree; POINTER_TYPE base_capacity = 0; TYPE (*g)(TYPE, TYPE); TYPE neutral; TYPE result_on_segment_in ( POINTER_TYPE v, POINTER_TYPE tl, POINTER_TYPE tr, POINTER_TYPE l, POINTER_TYPE r ) { if (l > r) return neutral; else if (l == tl && r == tr) return SegmentTree[v]; else { POINTER_TYPE tm = (tl + tr) / 2; return g(result_on_segment_in(v*2, tl, tm, l, min(r,tm)), result_on_segment_in(v*2+1, tm+1, tr, max(l,tm+1), r)); } } void make_monoid_and_fill_rest(TYPE *NewTree, const POINTER_TYPE &n, TYPE f(TYPE, TYPE), const TYPE &neutr) { g = f; neutral = neutr; for(POINTER_TYPE i = base_capacity+n; i < 2*base_capacity; ++i) { NewTree[i] = neutral; } for(POINTER_TYPE i = base_capacity-1; i > 0; --i) { NewTree[i] = g(NewTree[2*i], NewTree[2*i+1]); } SegmentTree = NewTree; } void fix_capacity(const POINTER_TYPE &base_array_size) { for (base_capacity = 1; base_capacity < base_array_size; base_capacity <<= 1); } public: void read_and_construct(const POINTER_TYPE amount_of_elements, TYPE preprocessing_function(const POINTER_TYPE&), TYPE f(TYPE, TYPE), const TYPE neutr) { fix_capacity(amount_of_elements); TYPE *NewTree = new TYPE[base_capacity*2]; for(POINTER_TYPE i = 0; i < amount_of_elements; ++i) { NewTree[base_capacity+i] = preprocessing_function(i); } make_monoid_and_fill_rest(NewTree, amount_of_elements, f, neutr); } void assign(const POINTER_TYPE index, const TYPE new_value) { SegmentTree[base_capacity+index] = new_value; for (POINTER_TYPE i = (base_capacity+index)/2; i > 0; i /= 2) { SegmentTree[i] = g(SegmentTree[2*i], SegmentTree[2*i+1]); } } TYPE result_on_segment (POINTER_TYPE l, POINTER_TYPE r) { return result_on_segment_in(1, 0, base_capacity-1, l, r); } }; struct leaf { unsigned int number, amount; leaf() { number = 2000000; amount = 0; } leaf(unsigned int a) { number = a, amount = 0; } }; leaf max_leafs(leaf a, leaf b) { return (a.amount == b.amount) ? (a.number < b.number) ? a : b : (a.amount > b.amount) ? a : b; } leaf constructor(const unsigned int &i) { return leaf(i); } int main() { segment_tree <unsigned int, leaf> box; box.read_and_construct(1000001, constructor, max_leafs, leaf()); unsigned int n, index; char operation; leaf tmp; scanf("%u\n", &n); ++n; while (--n) { scanf("%c %u\n", &operation, &index); tmp = box.result_on_segment(index, index); if (operation == '+') ++tmp.amount; else --tmp.amount; box.assign(index, tmp); printf("%u\n", (box.result_on_segment(0, 1000000)).number); } return 0; } |
Проанализируем задачу: так как требуется вывести число, которое встречается чаще всего на листках, находящихся в ящике после запроса удаления/добавления, а если таких чисел несколько, то вывести наименьшее, то задачу можно переформулировать следующим образом:
«Даётся последовательность (массив) объектов leaf [latex]x_{1}[/latex], [latex]x_{2}[/latex], [latex]x_{3}[/latex], [latex]\ldots[/latex], [latex]x_{999999}[/latex], [latex]x_{1000000}[/latex], представляющих из себя пару (number, amount)[latex]=x_{i}=\left(i, a_{i}\right) \in {\mathbb{N}_{0}}^{2}[/latex], где первые элементы пар [latex]i[/latex] представляет из себя число/номер листка, а вторые элементы [latex]a_{i}[/latex] — число листков с этим номером. Изначально все элементы пар [latex]a_{i}[/latex] равны нулю (так как изначально ящик пуст). Для запросов первого типа [latex]+ x[/latex] необходимо увеличивать на единицу число [latex]a_{i}[/latex] объекта, у которого номер [latex]i[/latex] равен [latex]x[/latex], а для запросов второго типа — уменьшать. Для каждого запроса необходимо вывести число [latex]j[/latex], удовлетворяющее условию [latex]j = \min\limits_{i \in \mathbb{K}}{i}[/latex], где [latex]\mathbb{K} = \{i \mid a_{i} = \max\limits_{k \in \{1, 2, \ldots, 1000000\}}{a_{k}} \}[/latex]».
Иными словами, число [latex]i[/latex] соответствует некоторому элементу [latex]x_{i} = \left(i, a_{i}\right)[/latex], который в свою очередь определяется операцией такой, что [latex]i[/latex] и [latex]a_{i}[/latex] удовлетворяют приведённым выше условиям. Очевидно, что данная операция является ассоциативной (как объединение минимума и максимума на заданных множествах), а потому для решения задачи воспользуемся универсальным деревом отрезков.
Создадим дерево отрезков box методом read_and_construct из объектов leaf. Так как нумерация листков начинается с единицы, а их число не превышает [latex]10^{6}[/latex], зададим размер базы дерева отрезков [latex]10^{6}+1[/latex], добавив неё элемент с индексом [latex]0[/latex]. Модифицируем метод read_and_construct таким образом, чтобы в функцию-препроцессор передавался номер элемента [latex]i[/latex], дабы была возможность задавать элементам [latex]x_{i}[/latex] их первоначальные значения [latex]\left(i, 0\right)[/latex]. Вышеупомянутую операцию назовём max_leafs и определим таким образом, чтобы она принимала два аргумента [latex]x_{i} = \left(i, a_{i}\right)[/latex] и [latex]x_{j} = \left(j, a_{j}\right)[/latex] и возвращала тот из них, у которого значение [latex]a[/latex] является большим, а в случае равенства этих значений — аргумент с меньшим индексом. Нейтральным элементом относительно данной операции будет, очевидно, пара [latex]\left(+\infty, 0\right)[/latex], но в силу того, что номера элементов не превышают [latex]10^6[/latex], вместо неё мы будем пользоваться парой [latex]\left(2 \times 10^{6}, 0\right)[/latex].
Далее при запросах вида [latex]+ x[/latex] будем увеличивать соответствующее значение [latex]a_{x}[/latex] пары [latex]\left(x, a_{x}\right)[/latex] на единицу, а при запросах вида [latex]- x[/latex] — уменьшать. Для обоих запросов будем выводить номер заданного листка, который удовлетворяет приведённым в задаче условиям, с использованием метода result_on_segment на всём отрезке [latex]\left[0, 10^{6}\right][/latex]. Ответом для каждого запроса будет значение number пары, которую вернёт метод.
Примечание: ситуация когда ящик становится пустым нигде не обрабатывается, но в силу того, что мы определили массив на отрезке [latex]\left[0, 10^{6}\right][/latex] вместо [latex]\left[1, 10^{6}\right][/latex] в нём всегда есть пара [latex]\left(0, 0\right)[/latex] (листки с номером [latex]0[/latex], число (значение [latex]b[/latex]) которых всегда равно [latex]0[/latex] в силу того, что листки с номером [latex]0[/latex] в ящик не добавляются). Так как определённая нами операция всегда возвращает минимальный номер листка, число которого максимально, то в случае, когда ящик пуст (т.е. значения всех [latex]a_{i} = 0, i = 0, 1, \ldots, 10^{6}[/latex]) будет выводится номер листка [latex]0[/latex]. Этот побочный эффект данного нами определения массива решает эту ситуацию и завершает решение задачи.
Задача RSQ (Range Sum Query). Вам дан массив, необходимо отвечать на запросы получения суммы на отрезке и изменение одного элемента массива.
Ссылка на задачу на codeforces.com.
Имя входного файла: rsq.in
Имя выходного файла: rsq.out
Ограничение по памяти: 2 секунды
Ограничение по времени: 256 мегабайт
Входной файл в первой строке содержит два числа [latex]n[/latex] [latex]\left(1 \le n \le 10^{5} \right)[/latex] — размер массива и [latex]m[/latex] [latex]\left(1 \le m \le 10^{5} \right)[/latex] — количество запросов. Во второй строке задано начальное состояние массива [latex]a_{1}[/latex], [latex]a_{2}[/latex], [latex]\ldots[/latex], [latex]a_{n}[/latex] [latex]\left( -10^{5} \le a_{i} \le 10^{5} \right)[/latex].
Далее идёт [latex]m[/latex] строк с запросами вида [latex]t[/latex] [latex]x[/latex] [latex]y[/latex] [latex]\left( 0 \le t \le 1 \right)[/latex]. Если [latex]t = 0[/latex], тогда на запрос нужно вывести сумму элементов массива с индексами от [latex]x[/latex] до [latex]y[/latex] (в данном случае [latex]1 \le x \le y \le n[/latex]). Если [latex]t = 1[/latex], тогда надо присвоить элементу массива с индексом [latex]x[/latex] значение [latex]y[/latex] (в этом случае [latex]1 \le x \le n[/latex], [latex]-10^{5} \le y \le 10^{5}[/latex]).
На каждый запрос суммы отрезка выведите одно число в новой строке — запрашиваемая сумма.
rsq.in | rsq.out |
---|---|
5 3 1 2 3 4 5 0 1 5 1 1 -14 0 1 5 |
15 0 |
8 2 7 3 -10 4 1 2 5 6 0 2 4 0 5 7 |
-3 8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
#include <iostream> #include <fstream> using namespace std; int main() { ifstream cin("rsq.in"); ofstream cout("rsq.out"); ios::sync_with_stdio(false); unsigned int n, m, i; long long sum = 0, sum_k; int *a, x, y; bool t; cin >> n >> m; n++; a = new int[n]; for (i = 1; i < n; i++) { cin >> a[i]; sum += a[i]; } const unsigned int ndiv2 = n/2; while (m--) { cin >> t >> x; if (t) { sum -= a[x]; cin >> a[x]; sum += a[x]; } else { cin >> y; y++; if (y - x > ndiv2) { sum_k = sum; for (i = 1; i < x; i++) { sum_k -= a[i]; } for (i = y; i < n; i++) { sum_k -= a[i]; } } else { sum_k = 0; for (; x < y; x++) { sum_k += a[x]; } } cout << sum_k << endl; } } return 0; } |
Основная идея приведённого выше решения этой задачи заключается в оптимизации обработки запросов суммы построением дерева отрезков.
Сохраним сумму всех элементов массива в переменной
sum. Теперь, если нам дан запрос суммы на отрезке [latex]\left[ x; y \right][/latex], то если [latex]y — x > \frac{n}{2}[/latex] (то есть если данный отрезок содержит больше элементов, чем половина всего отрезка) то считаем сумму элементов на отрезке [latex]\left[ 1; x-1 \right] \cup \left[ y+1; n \right] = \left[ 1; n \right] \setminus \left[ x; y \right][/latex] и отнимаем от суммы всех элементов, иначе (если [latex]y — x \le \frac{n}{2}[/latex], то) просто считаем сумму элементов на отрезке [latex]\left[ x; y \right][/latex]. Если же поступает запрос на замену значения элемента, то вычитаем из
sum старое значение и прибавляем новое.
Таким образом, максимальная сложность запросов суммы (при простом подходе к задаче) уменьшается вдвое.
Примечание: [latex]GCD[/latex] — Greatest common divisor (Наибольший общий делитель, НОД).
Даны натуральные числа [latex]m[/latex], [latex]n_1[/latex], [latex]\ldots[/latex], [latex]n_m[/latex] [latex]m \ge 2[/latex]. Вычислить [latex]GCD \left( n, \ldots, n_m \right)[/latex], воспользовавшись для этого соотношением [latex]GCD \left( n, \ldots, n_k \right) = GCD \left( GCD \left( n, \ldots, n_{k-1} \right), n_k \right)[/latex] [latex]\left( k = 3, \ldots, n \right)[/latex] и алгоритмом Евклида.
Количество чисел [latex]m[/latex]; числа [latex]n_1[/latex], [latex]\ldots[/latex], [latex]n_m[/latex].
Входные данные | Выходные данные | ||||
---|---|---|---|---|---|
2 | 3 | 4 | 1 | ||
2 | 4 | 8 | 4 | ||
4 | 24 | 23 | 40 | 90 | 1 |
4 | 36 | 48 | 20 | 24 | 4 |
3 | 30 | 738 | 1926 | 6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> using namespace std; unsigned long long gcd(unsigned long long m, unsigned long long n) { return (n != 0) ? gcd(n, m%n) : m; } int main() { unsigned long long m, n, result; cin >> m >> result; for (unsigned long long i = 2; i <= m; i++) { cin >> n; result = gcd(result, n); if (result == 1) m = 1; //same as break } cout << result << endl; return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import java.util.*; public class Main { public static long gcd(long m, long n) { if (n != 0) return gcd(n, m%n); else return m; } public static void main (String[] args) throws java.lang.Exception { Scanner in = new Scanner(System.in); long m = in.nextLong(), n, result = in.nextLong(); for(long i = 2; i <= m; ++i) { n = in.nextLong(); result = gcd(result, n); if (result == 1) m = 1; //same as break } System.out.println(result); } } |
Для решения данной задачи необходимо использовать данную в условии формулу [latex]GCD \left( n, \ldots, n_k \right) = GCD \left( GCD \left( n, \ldots, n_{k-1} \right), n_k \right)[/latex] [latex]\left(\right)[/latex].
Также необходимо воспользоваться алгоритмом Евклида для реализации рекурсивной функции [latex]GCD[/latex]:
Пусть [latex]m[/latex] и [latex]n[/latex] — одновременно не равные нулю целые неотрицательные числа и пусть [latex]m \ge n[/latex]. Тогда если [latex]n=0[/latex], то [latex]GCD\left(n, m\right)=m[/latex], а если [latex]n\ne0[/latex], то для чисел [latex]m[/latex], [latex]n[/latex] и [latex]r[/latex], где [latex]r[/latex] — остаток от деления [latex]m[/latex] на [latex]n[/latex], выполняется равенство [latex]GCD\left(m, n\right)=GCD\left(n, r\right)[/latex]. (задача 89 задачника С. Абрамова)
Программа записывает в переменную
m число [latex]m[/latex], а в
result — [latex]n_1[/latex].
Затем, используя формулу [latex]\left(\right)[/latex], программа до окончания цикла считывает следующие числа из последовательности поверх предыдущих в переменную
n и находит сперва [latex]GCD\left(n_1, n_2\right)=x_1[/latex], [latex]GCD\left(x_1, n_3 \right)=x_2[/latex], затем [latex]GCD\left(x_2, n_4\right)=x_3[/latex] и так далее, вплоть до нахождения [latex]GCD[/latex] всех чисел, постоянно записывая новые [latex]GCD[/latex] поверх старых в переменную
result. В итоге, программа выводит результирующий [latex]GCD[/latex], который и является ответом.
Вводятся некоторые числа вещественного типа. Вывести их в обратном порядке.
Некие числа вещественного типа.
Введённые числа в обратном порядке.
Входные данные | Выходные данные | Входные данные | Выходные данные | Входные данные | Выходные данные |
---|---|---|---|---|---|
2 4 1 |
1 4 2 |
4 9 -6 |
-6 9 4 |
0.568 0.925 -0.056 |
-0.056 0.925 0.568 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> using namespace std; void reverse() { double x; if (cin >> x) { reverse(); cout << x << "\n"; } } int main() { reverse(); return 0; } |
Основная суть программы заключается в использовании рекурсивной функции. Главная функция main обращается к функции reverse, которая будет считывать поток чисел. Если поток чисел продолжается, то функция будет заново обращаться сама к себе и считывать следующие числа. Когда поток закончится, функция прекратит считывать данные, после чего начнётся вывод.
Принцип работы рекурсивной функции
reverse:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <cstdio> #include <cmath> void reverse() { double x; if (scanf("%lf", &x) > 0) { reverse(); printf("%.4f\n", sqrt(x)); } } int main() { reverse(); return 0; } |
Используйте метод золотого сечения для того, чтобы отыскать с точностью [latex]\varepsilon[/latex] локальный максимум функции на отрезке
.
Точка локального максимума и локальный максимум в формате [latex](x_{max}, y_{max})[/latex].
[latex]\varepsilon[/latex] | [latex]a[/latex] | [latex]b[/latex] | [latex](x_{max}, y_{max})[/latex] |
[latex]0.001[/latex] | [latex]1.05[/latex] | [latex]2.2[/latex] | [latex](1.74435, 0.951781)[/latex] |
[latex]0.0001[/latex] | [latex]1.05[/latex] | [latex]2.2[/latex] | [latex](1.74417, 0.951781)[/latex] |
[latex]0.0001[/latex] | [latex]5.7[/latex] | [latex]8[/latex] | [latex](7.57498, 3.68407)[/latex] |
[latex]0.0001[/latex] | [latex]3[/latex] | [latex]4[/latex] | [latex](3.61901, 2.31289)[/latex] |
Для начала проанализируем данную нам функцию. Найдем ее область определения.
[latex]D(f) = x^2 + 1 + \cos x > 0 [/latex]
Таким образом, функция определена на всей числовой оси и мы имеем право рассматривать функцию для любого значения аргумента (также это видно по графику).
Однако следует помнить о том, что используемый нами метод золотого сечения принадлежит к группе симметричных методов и накладывает некоторые ограничения на исследуемую функцию. Применимость данного метода гарантируется только для непрерывных, унимодальных функций.
Унимодальная функция — это функция, которая монотонна на обе стороны от точки максимума [latex]x_{max}[/latex].
Отсюда следует, что если функция [latex]f(x)[/latex] унимодальна на отрезке [latex][a; b][/latex], то максимум этой функции единственен, а локальные минимумы обязательно располагаются на его концах. Так как данная нам функция не является таковой, то для корректного применения метода и получения желаемого результата мы будем собственноручно задавать такие отрезки, на которых представленная функция унимодальна (их несложно выделить по графику).
Проведя анализ функции, обратимся к самому методу золотого сечения.
Для того чтобы найти определенное значение функции на заданном отрезке, отвечающее заданному критерию поиска (в нашем случае максимум), рассматриваемый отрезок требуется поделить в пропорции золотого сечения в обоих направлениях, то есть выбираются две точки [latex]x_1[/latex] и [latex]x_2[/latex] такие, что
[latex]\frac{b — a}{b — x_1}[/latex] [latex]= \frac{b — a}{x_2 — a} =[/latex] [latex]\varphi[/latex] [latex] = \frac{1 + \sqrt{5}}{2}[/latex]
То есть точка [latex]x_1[/latex] делит отрезок [latex][a; x_2][/latex] в отношении золотого сечения. Аналогично [latex]x_2[/latex] делит отрезок [latex][x_1; b][/latex] в той же пропорции. Для нахождения максимума выполняем следующую последовательность действий:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <iostream> #include <math.h> using namespace std; const double goldenRatio = (1 + sqrt(5)) / 2; // "Золотое" число // Рассматриваемая нами функция double function(double x) { return log(1 + x * x - cos(x)) - pow(M_E, sin(M_PI * x)); } int main() { double a, b; // Концы отрезка double accuracy; // Точность, с которой мы находим локальный максимум double x1, x2; // Точки, делящие текущий отрезок в отношении золотого сечения cin >> a >> b >> accuracy; while (fabs(b - a) > accuracy) { x1 = b - (b - a) / goldenRatio; x2 = a + (b - a) / goldenRatio; if (function(x1) <= function(x2)) // Условие для поиска максимума a = x1; else b = x2; } // Выполняем, пока не достигнем заданной точности cout << "(" << (a + b) / 2 << ", " << function((a + b) / 2) << ")"; return 0; } |
Условие задачи
Вычислите с точностью [latex]\varepsilon[/latex] значение функции [latex]f(x)=\arcsin x[/latex].
При вычислениях допустимо использовать только арифметические операции.
№ | [latex] x [/latex] | [latex] arcsin x [/latex] |
1 | -1 | -1.56709 |
2 | -0.5 | -0.523599 |
3 | 0 | 0 |
4 | 0.5 | 0.523599 |
5 | 0.7071067 | 0.785398 |
6 | 0.8660254 | 1.0472 |
Чтобы разложить тригонометрическую функцию только арифметическими операциями, нужно воспользоваться формулами Тейлора.
Ряд Тейлора для функции [latex]\arcsin x[/latex]:
[latex]\arcsin x = \sum_{n=0}^{\infty} \frac{(2n)!}{4^n (n!)^2 (2n+1)} x^{2n+1}[/latex]
или:
[latex]\arcsin x = x + \frac{x^3}{6} + \frac{3x^5}{40} + \cdots[/latex]
Вводим переменную, которая будет считать арксинус — [latex]arcsin[/latex].
Так как первый член — [latex]x[/latex], то начальное значение [latex]\arcsin =x[/latex] и [latex]a=x[/latex]. [latex]a[/latex] — это слагаемые суммы, оно будет изменятся с каждым последующим значением [latex]n[/latex].
Теперь нужно узнать на сколько домножать первое слагаемое из ряда Тейлора, чтобы получить второе:
[latex]\frac{(2(n+1))!\cdot x^{2(n+1)+1}}{4^{n+1}((n+1)!)^2 (2(n+1)+1)} \cdot \frac{4^n (n!)^2 (2n+1)}{(2n)!\cdot x^{2n+1}} = \frac{(2n+1)^2 x^2}{2(2n+3)(n+1)}[/latex]Видно, что эта функция сначала возрастает, а потом убывает ( [latex]x\leq 1[/latex] )
[latex]\frac{(2n+1)^2 x^2}{2(2n+3)(n+1)}[/latex], поэтому [latex]a[/latex] будет уменьшаться. Мы задаем точность [latex]\varepsilon[/latex] и пока [latex]a > \varepsilon[/latex] мы вычисляем сумму
[latex]\arcsin +=a[/latex].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <cmath> using namespace std; int main() { int n=0; double x; cin >> x; double a=x, arcsin=x, E=0.1e-5; while (abs(a*=(x*x*(2*n+1)*(2*n+1)/(2*(n+1)*(2*n+3))))>E) { arcsin+=a; n++; } cout << arcsin; return 0; } |
Задача. Вычислите с точностью [latex]\epsilon[/latex] значение функции [latex]f\left( x \right) = \sin x[/latex]. При вычислениях допустимо использовать только арифметические операции.
Код программы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <iostream> #include <cmath> using namespace std; double sin (double x, double e) { double k, a = x; double s = x; int n=1; while (abs(a) > e) { k = - x * x / (2 * n * (2 * n + 1)); a *= k; s += a; n++; } return s; } int main () { double x, e; cin >> x >> e; cout << endl << sin(x, e); } |
Тесты
Входные данные | Входные данные | Выходные данные |
x | e | sin(x) |
1 | 0,01 | 0,841471 |
3 | 0,01 | 0,14112 |
4 | 0,001 | -0,756802 |
7 | 0,0001 | 0, 656987 |
Решение
Необходимо использовать формулу Тейлора, а именно ряд Маклорена, чтобы представить функцию
[latex]f(x)[/latex] = [latex]\sin x[/latex]Эта формула имеет такой вид [latex]\sin x[/latex] = [latex]\sum _ { n=0 }^{ \infty }{ { (-1) }^{ n } } \frac { { x }^{ 2n+1 } }{ (2n+1)! }[/latex].
Подключаем заголовочный файл cmath для использования функции abs(). Построим реккурентную формулу для [latex]x_n[/latex] через [latex]x_{n-1}[/latex] для [latex]n > 1 \left(x_0=x\right)[/latex]. Для этого найдем отношение последующего члена ряда к предыдущему [latex]k = \frac{x_n}{x_{n-1}} = -\frac{x^2}{2n\cdot(2n + 1)}[/latex].
Используем функцию while, чтобы проверить является ли член ряда [latex]x_n[/latex] больше [latex]e[/latex].
Дано действительное число [latex]a[/latex]. Вычислить [latex]f(a)[/latex], если
[latex]f(x) = \begin{cases}0, & x \le 0;\\x^2 — x, & 0 < x \le 1;\\x^2 — \sin(\pi \cdot x^2), & x > 1 \end{cases}[/latex]
Находим промежуток, которому принадлежит [latex]a[/latex]. Если [latex]a \in (-\infty;0][/latex], то [latex]f(a) = 0[/latex], если [latex]a \in (0;1][/latex], то [latex]f(a) = a^2 — a[/latex], в остальных случаях [latex]f(a) = a^2 — \sin(\pi \cdot a ^ 2)[/latex].
Входные данные | Выходные данные |
0 | 0 |
1 | 0 |
2 | 4 |
ideone: ссылка
1 2 3 4 5 6 7 8 9 10 |
#include <iostream> #include <cmath> using namespace std; int main() { double a; cin >> a; cout << (a <= 0 ? 0 : a <= 1 ? a * a - 1 : a * a - sin(M_PI * a * a)) << endl; return 0; } |
Метод Рунге-Кутта. Найти приближенное решение обыкновенного дифференциального уравнения [latex]y^\prime=f(x,y), y(a)=y_{0}[/latex] методом Рунге-Кутта пятого порядка на отрезке [latex][a,b][/latex] с заданным шагом [latex]h[/latex]. Значения функции [latex]y(x)[/latex] в узловых точках вычисляется по формуле: [latex]y_{i+1}=y_{i}+\frac{h}{6}(k_{1}+2k_{2}+2k_{3}+k_{4}), i=0,1,2,\cdots[/latex], где [latex]k_{1}=f(x_{i},y_{i}); k_{2}=f(x_{i}+\frac{h}{2},y_{i}+\frac{h}{2}k_{1});[/latex][latex]k_{3}=f(x_{i}+\frac{h}{2},y_{i}+\frac{h}{2}k_{2}); k_{4}=f(x_{i}+h,y_{i}+hk_{3})[/latex].
Решим дифференциальное уравнение такого вида: [latex]y^\prime=x+y[/latex] при начальном условии [latex]y(0)=1[/latex] на отрезке [latex][0, 0.5][/latex] с шагом интегрирования [latex]h=0.1[/latex]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> using namespace std; double fdif(double x,double y) { return x+y; } int main() { double k1, k2, k3, k4, dy, x, y0, a, b, h; scanf("%lf %lf %lf %lf", &a, &b, &h, &y0); for ( x ; x <= b ; x += h ) { k1 = fdif (x , y0); k2 = fdif (x + h / 2 , y0 + h / 2 * k1); k3 = fdif (x + h / 2 , y0 + h / 2 * k2); k4 = fdif (x + h , y0 + h * k3); y0 += h * ( k1 + 2 * k2 + 2 * k3 + k4 ) / 6; } printf("%lf", y0); return 0; } |
В программе присутствует функция, которой мы передаем параметры [latex]x, y[/latex] и которая возвращает само дифференциальное уравнение. Далее, в цикле высчитываем значения [latex]k_{1},k_{2},k_{3},k_{4}[/latex], передавая каждый раз параметры в функцию с шагом [latex]h[/latex] до тех пор пока не дойдем до конца промежутка. После завершения цикла выводим значение [latex]y_{0}[/latex].
Задача. Даны натуральные числа [latex]n, a_{1}, a_{2},\ldots, a_{n} (n\geq 4)[/latex]. Числа [latex]a_{1}, a_{2},\ldots , a_{n}[/latex] — это измеренные в сотых долях секунды результаты [latex]n[/latex] спортсменов в беге на [latex]100[/latex] м. Составить команду из четырёх лучших бегунов для участия в эстафете [latex]4\times100[/latex], т.е. указать одну из четверок натуральных чисел [latex]i, j, k, l[/latex], для которой [latex]1\leq i\leq j\leq k\leq l\leq n[/latex] и [latex]a_{i} + a_{j}+a_{k} + a_{l}[/latex] имеет наименьшее значение.
n | c | Результаты бега спортсменов | Номера спортсменов, избранных для команды | Комментарий |
6 | 3 | 11.77 12.34 12.14 11.15 11.16 11.40 | 4 5 6 | Пройден |
6 | 4 | 11.68 0 12.15 11.54 11.26 11.00 | Введен отрицательный или нулевой результат | Не пройден |
6 | 2 | 11.68 -12.34 12.14 11.55 11.29 11.00 | Введен отрицательный или нулевой результат | Не пройден |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
#include <iostream> #include <algorithm> #include <limits> using namespace std; int mini(double x[],int n) //Функция, которая возвращает номер бегуна с наилучшим результатом. { double minn = numeric_limits<double>::infinity(); int mini; for (int i = 0; i < n ; i ++)//Цикл для нахождения минимального значения. { double t = x[i]; if (t <= minn) { mini = i; minn = t; } } return mini; //Возвращение номера минимального значения } void team(double x[], int n, int c)//Функция выводящая на экран номера наилучших спортсменов. { int counters[c]; //Массив номеров бегунов. for (int i = 0; i < c ; i ++) { counters[i] = mini( x , n ); x[ counters[i] ] = numeric_limits<double>::infinity(); } sort(counters, counters + c); //Сортировка номеров бегунов for (int i = 0; i < c ; i ++) { cout<<counters[i] + 1 <<" "; } } int main() { int n, c, k = 0; //Описание переменных для хранения входных данных./ cin>>n>>c; double x[n]; //Описание массива для хранения входных данных.// for (int i = 0; i < n ; i ++) { cin>>x[i]; if (x[i] <= 0) //Проверка массива на отрицательный (либо нулевой) элемент. { cout<<"Введен отрицательный или нулевой результат"; return 0; } } team(x, n ,c); return 0; } |
В строках
41 42 43 44 45 46 47 48 49 |
for (int i = 0; i < n ; i ++) { cin>>x[i]; if (x[i] <= 0) //Проверка массива на отрицательный (либо нулевой) элемент. { cout<<"Введен отрицательный или нулевой результат"; return 0; } } |
мы заполняем массив элементами из входящего потока, при этом уже зная n (количество этих элементов), считав его из входящего потока заранее и проверяем на наличие отрицательного элемента либо нуля (если таковой существует, то выводим сообщение об ошибке и завершаем выполнение программы.
В конечном итоге, применяем функцию team и получаем, собственно, ответ.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import java.util.*; import java.lang.*; import java.io.*; class Runners { public static void main (String[] args) throws java.lang.Exception { //Описание переменных для хранения входных данных./ Scanner in = new Scanner(System.in); int n = in.nextInt(); int c = in.nextInt(); int[] counters = new int[c]; //Массив номеров бегунов. int k = 0; double[] x = new double[n]; //Описание массива для хранения входных данных.// for (int i = 0; i < n; i++) x[i] = in.nextDouble(); for (int i = 0; i < c; i++) { double minn = Double.POSITIVE_INFINITY; int mini = 0; for (int j = 0; j < n; j++) //Цикл для нахождения минимального значения. { if (x[j] <= minn) { mini = j; minn = x[j]; } } counters[i] = mini; x[counters[i]] = Double.POSITIVE_INFINITY; } Arrays.sort(counters, 0, c); //Сортировка номеров бегунов for (int i = 0; i < c ; i ++) System.out.printf(counters[i] + 1 + " "); } } |
Задача: В задаче задана функция и её разложение в ряд или произведение. Численно убедится в справедливости равенства, для чего для заданного значения аргумента [latex] x [/latex] вычислить левую его часть и разложение, стоящее в правой части, с заданной погрешностью [latex]\varepsilon\[/latex]. Испытать разложение на сходимость при разных значениях аргумента, оценить скорость сходимости, для чего вывести число итераций [latex] n [/latex] (слагаемых или сомножателей), необходимых для достижения заданной точности.
[latex]\sin \left(x \right) = x \left(1 — \frac{x^{2}}{\pi^{2}} \right) \left( 1 — \frac{x^{2}}{4\pi^{2}} \right) \ldots \left(1 — \frac{x^{2}}{ \left( n-1 \right)^{2}\pi^{2}} \right)[/latex]
Тесты:
x | n-Excel | sin — Excel | deviation — Excel | e — input | exact sinus | n — program | deviation — program |
12 | 22 | -1,029367 | 0.56 | 0.56 | -0.536573 | 22 | 0.524789 |
5 | 7 | -1,346966 |
0.54 | 0.54 | -0.958924 | 7 | 0.461469 |
2.5 | 2 | 0,771704 | -1.15 | -1.15 | 0.598472 | 2 | -0.318384 |
1 | 2 | 0,875915 | -1.38 | -1.38 | 0.841471 | 2 | -0.057208 |
0 | 2 | 0 | -0.53 | -0.53 | 0 | 2 | 0 |
-1 | 2 | -0,875915 | 0.3 | 0.3 | -0.841471 | 2 | 0.057208 |
-2.5 | 6 | -0,659746 | 0.08 | 0.08 | -0.598472 | 6 | 0.073087 |
-5 | 4 | 1,700161 | -1.62 | -1.62 | 0.958924 | 4 | -1.061024 |
-12 | 12 | 1,755690 | -1.63 | -1.63 | 0.536573 | 12 | -1.417062 |
Код программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <stdio.h> #include <math.h> double pow2( double x ) //вторая степень { return x*x; } int main() { // рабочие переменные double x, e, d, r; unsigned int n, nMax = 0xffffffff; // лимит числа итераций чтобы избежать бесконечного цикла // ввод данных - аргумента функции и заданной погрешности scanf("%lf", &x); scanf("%lf", &e); for( r = x, n = 2; n < nMax; n++ ) // основной цикл вычислений { r = r * ( 1 - pow2( x ) / ( pow2( n - 1 ) * pow2( M_PI ) ) ); d = sin( x ) - r ; if( fabs( d ) <= fabs( e ) ) break; } // вывод результата printf("sin(x) = %lf\n", sin( x ) ); printf("calculated sinus = %lf\n", r ); printf("inaccuracy = %lf\n", d ); printf("number of iterations: %d\n", n ); return 0; } |
Код программы на языке Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import java.util.*; import java.lang.*; import java.io.*; class SinusApp { public static Double scanDouble( Scanner in ) { return ( ( in.hasNextDouble() ) ? in.nextDouble() : null ); } public static double pow2( double x ) //вторая степень { return x*x; } public static void main( String[] args ) { // рабочие переменные double x, e, d, r; long n, nMax = Long.MAX_VALUE; // лимит числа итераций чтобы избежать бесконечного цикла // ввод данных - аргумента функции и заданной погрешности Scanner in = new Scanner(System.in); x = scanDouble( in ); e = scanDouble( in ); in.close(); for( d = 0, r = x, n = 2; n < nMax; n++ ) // основной цикл вычислений { r = r * ( 1 - pow2( x ) / ( pow2( n - 1 ) * pow2( Math.PI ) ) ); d = Math.sin( x ) - r ; if( Math.abs( d ) <= Math.abs( e ) ) break; } // вывод результата System.out.printf("sin(x) = %f\n", Math.sin( x ) ); System.out.printf("calculated sinus = %f\n", r ); System.out.printf("inaccuracy = %f\n", d ); System.out.printf("number of iterations: %d\n", n ); } } |
Ссылка:http://ideone.com/nZluY8
Программа состоит из следующих частей:
Правильность результата проверялась на калькуляторе. тестирование показало, что правильные значения получаются только при очень большом n . Только начиная с десятков тысяч результат близок к показанию калькулятора.
Данные для проверки подготавливались в Excel ввиду относительно большого количества итераций, необходимых для расчётов. Полученная погрешность с точным значением синуса использовались как входное [latex]e[/latex]. Результирующее количество итераций программы сравнивалось с числом итераций, сделанных в Excel. Ввиду того, что double намного точнее чем значения в Excel, возможны различия в числе итераций ( назначенных ).
Ссылка на ideone.com: http://ideone.com/fork/Wh91nH
Задача: Дано действительное число [latex]a[/latex]. Для функции [latex]f(x)[/latex], график которой представлен на рисунке, вычислить [latex]f(a)[/latex].
График:
Тесты:
a | f(a) |
1 | 1 |
3.2 | -0.015371 |
6 | -0.027469 |
0 | 0 |
-1 | 1 |
-2.5 | 2.5 |
1.5 | 1 |
1.8 | 1 |
1.001 | 1 |
Код программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include <stdio.h> int main(void) { // Объявление переменных a, y, k, b типа float для хранения данных double a; double y; double k; double b; // Ввод пользователем значений переменной а с помощью scanf scanf("%lf", &a); // Вычисление и вывод результата по формуле с предварительным сравнением значения а, if( a <= 0 ) { k = -1; b = 0; } else if ( a <= 1 ) { k = 1; b = 0; } else if ( a < 2 ) { k = 0; b = 1; } else { k = -2; b = 5; } y = k*a + b; printf("result is %lf", y); // Завершение программы return 0; } |
Код программы на языке Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
import java.util.*; import java.lang.*; import java.io.*; class GraphicApp { public static Double scanDouble( Scanner in ) { return ( ( in.hasNextDouble() ) ? in.nextDouble() : null ); } public static void main( String[] args ) { // ќбъ¤вление переменных a, y, k, b типа double дл¤ хранени¤ данных double a; double y; double k; double b; Scanner in = new Scanner(System.in); a = scanDouble( in ); in.close(); // ¬ычисление и вывод результата по формуле с предварительным сравнением значени¤ а, if( a <= 0 ) { k = -1; b = 0; } else if ( a <= 1 ) { k = 1; b = 0; } else if ( a < 2 ) { k = 0; b = 1; } else { k = -2; b = 5; } y = k*a + b; System.out.printf("result is %f\n", y); } } |
Ссылка:http://ideone.com/e6UFys
Результат вычисляем по формуле:
[latex]y = ka + b[/latex]
Программа состоит из следующих частей:
Программа сравнивает значение переменной [latex]a[/latex] с значениями переменной [latex]x[/latex] на четырёх диапазонах, и в зависимости от диапазона использует для функции [latex]y = ka + b[/latex] нужные значения [latex]k[/latex] и [latex]b[/latex]. Так вычисляется [latex]f(a)[/latex].
Ссылка на ideone.com : http://ideone.com/N2toyp
Задача. Дано действительное число [latex]a[/latex]. Для функции [latex]f\left(x \right)[/latex], график которой изображен, вычислить [latex]f\left(a \right)[/latex].
a | [latex]f\left(a \right)[/latex] | Комментарий |
7 | -49 | Пройден |
0 | 0 | Пройден |
-2 | 2 | Пройден |
1 2 3 4 5 6 7 8 9 10 11 |
#include <stdio.h> #include <math.h> int main() { double a, y; scanf("%lf", &a); if (a > 0) y = -a * a; else y = -a; printf("%lg",y); return 0; } |
Для решения данной задачи требуется лишь проверка знака числа [latex]a[/latex]. Если [latex]a> 0[/latex], то [latex]f\left(a \right)[/latex] вычисляется как [latex]-a^{2}[/latex], а если [latex]a< 0[/latex], то [latex]f\left(a \right)[/latex] равна [latex]-a[/latex]. При [latex]a=0[/latex], [latex]f\left(a \right)=0[/latex]. Для проверки выполнения программы можно воспользоваться ссылкой.
Решение на Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import java.util.*; import java.lang.*; import java.io.*; class Ideone { public static void main (String[] args) throws java.lang.Exception { Scanner in = new Scanner(System.in); double a, y; a = in.nextDouble(); if (a > 0) y=-a*a; else y=-a; System.out.print(y); } } |
Для отправки комментария необходимо войти на сайт.