diff --git a/README.md b/README.md new file mode 100644 index 0000000..c91d44a --- /dev/null +++ b/README.md @@ -0,0 +1,218 @@ +# Алгоритмы решения прикладных задач, 1-й семестр, 2-я практика + +## Задания + +### Задание 1 + +Написать программу для поиска наибольшего общего делителя (числа вводятся с клавиатуры после запуска программы): +Нечетные варианты: наибольший делитель трех чисел методом деления (для поиска остатка отделения в языке C++ используется операция %) +Четные варианты: наибольший общий делитель четырех чисел метолом вычитания + +```cpp +// Функция для нахождения НОД двух чисел (метод деления) +int gcdDivision(int a, int b) { + while (b != 0) { + int temp = b; + b = a % b; + a = temp; + } + return a; +} + +// Функция для нахождения НОД трех чисел +int gcdOfThreeNumbers(int x, int y, int z) { + return gcdDivision(gcdDivision(x, y), z); +} + +// Функция для нахождения НОД двух чисел методом вычитания +int gcdSubtraction(int a, int b) { + while (a != b) { + if (a > b) { + a -= b; + } else { + b -= a; + } + } + return a; // или b, так как a == b +} + +// Функция для нахождения НОД четырех чисел +int gcdOfFourNumbers(int w, int x, int y, int z) { + return gcdSubtraction(gcdSubtraction(gcdSubtraction(w, x), y), z); +} +``` + +### Задание 2 + +Написать программу для факторизации заданного с клавиатуры числа методом простого перебора (указать простые множители и их кратность). Для анализа числа на простоту использовать решето Эратосфена + +```cpp +#include +#include + +#include "sieveoferatosthenes.cpp" + +// Функция для факторизации числа (метод простого перебора) +std::map factorize(int number) { + std::map factors; + std::vector primes = sieveOfEratosthenes(number); + + for (int prime : primes) { + if (prime * prime > number) break; + while (number % prime == 0) { + factors[prime]++; + number /= prime; + } + } + if (number > 1) { + factors[number]++; + } + + return factors; +} +``` + +### Задание 3 + +Написать программу для факторизации заданного с клавиатуры нечетного числа методом Ферма (указать простые множители и их кратность). Для анализа числа на простоту использовать решето Эратосфена + +```cpp +#include +#include +#include + +#include "sieveoferatosthenes.cpp" + +// Функция для факторизации числа методом Ферма +std::map fermatFactorize(int number) { + std::map factors; + + // Проверка на простоту + std::vector primes = sieveOfEratosthenes(static_cast(sqrt(number)) + 1); + for (int prime : primes) { + if (prime * prime > number) break; + while (number % prime == 0) { + factors[prime]++; + number /= prime; + } + } + + // Если число больше 1, применяем метод Ферма + if (number > 1) { + int a = static_cast(ceil(sqrt(number))); + int b2 = a * a - number; + int b = static_cast(sqrt(b2)); + + while (b * b != b2) { + a++; + b2 = a * a - number; + b = static_cast(sqrt(b2)); + } + + int factor1 = a - b; + int factor2 = a + b; + + // Добавляем найденные множители + factors[factor1]++; + factors[factor2]++; + } + + return factors; +} +``` + +### Задание 4 + +Написать программу для проверки на простоту числа Мерсенна с использование теста Люка-Лемера. С клавиатуры вводится номер числа Мерсенна + +```cpp +#include + +// Функция для проверки, является ли число простым +bool isPrime(int p) { + if (p <= 1) return false; + if (p <= 3) return true; + if (p % 2 == 0 || p % 3 == 0) return false; + for (int i = 5; i * i <= p; i += 6) { + if (p % i == 0 || p % (i + 2) == 0) return false; + } + return true; +} + +// Тест Люка-Лемера для проверки простоты числа Мерсенна +bool lucasLehmerTest(int p) { + if (p == 2) return true; // M_2 = 3, простое число + + // Вычисляем M_p = 2^p - 1 + long long M_p = (1LL << p) - 1; // 1LL << p эквивалентно 2^p + + // Начальное значение s + long long s = 4; + + // Выполняем тест + for (int i = 3; i <= p; ++i) { + s = (s * s - 2) % M_p; // s = s^2 - 2 + } + + // Если s % M_p == 0, то M_p простое + return s == 0; +} +``` + +### Задание 5 + +Написать программу для генерации последовательности из 10 пятизначных чисел фон Неймана + +```cpp +#include + +std::vector vonNeumannSequence(unsigned long int n) { + + std::vector sequence; + + for (int i = 0; i < 10; i++) + { + retry: + n = n*n; + n = (n / 100)%100000; + + if (n < 10000 || n >= 1000000) + { + goto retry; + } + + sequence.push_back(n); + } + + return sequence; +} +``` + +### Задание 6 + +Написать программу для поиска простых чисел по алгоритму «Решето Сундарама» + +```cpp +#include + +void Sundaram(bool A[], int N) +{ + int i, j; + for (i = 1; i <= N; i++) A[i] = true; + i = 1; j = 1; + while ((2 * i * j + i + j) <= N) + { + while (j <= (N - i) / (2 * i + 1)) + { + A[2 * i * j + i + j] = false; + j++; + } + i++; + j = i; + } + + for (i = 1; i <= N; i++) { + if (A[i]) std::cout << 2 * i + 1 << " "; + } +} +```