From d45769c4bcd0c27a4c142b07b27bd563393a9444 Mon Sep 17 00:00:00 2001 From: Nikolai Papin Date: Sat, 26 Oct 2024 09:11:25 +0300 Subject: [PATCH] First commit --- .gitignore | 3 ++ main.cpp | 0 sieveoferatosthenes.cpp | 49 +++++++++++++++++++++++++++++++ task1.cpp | 56 +++++++++++++++++++++++++++++++++++ task2.cpp | 46 +++++++++++++++++++++++++++++ task3.cpp | 65 +++++++++++++++++++++++++++++++++++++++++ task4.cpp | 61 ++++++++++++++++++++++++++++++++++++++ task5.cpp | 42 ++++++++++++++++++++++++++ task6.cpp | 32 ++++++++++++++++++++ 9 files changed, 354 insertions(+) create mode 100644 .gitignore create mode 100644 main.cpp create mode 100644 sieveoferatosthenes.cpp create mode 100644 task1.cpp create mode 100644 task2.cpp create mode 100644 task3.cpp create mode 100644 task4.cpp create mode 100644 task5.cpp create mode 100644 task6.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..87ca87e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.ccls +.ccls-cache +a.out diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..e69de29 diff --git a/sieveoferatosthenes.cpp b/sieveoferatosthenes.cpp new file mode 100644 index 0000000..befb456 --- /dev/null +++ b/sieveoferatosthenes.cpp @@ -0,0 +1,49 @@ +/* +* Реализация решета Эратосфена +*/ + +#include +#include +#include + +// Решето Эратосфена +std::vector sieveOfEratosthenes(int n) +{ + // 1. Выписываем подряд все числа от 2 до n + std::vector prime; + for (int i = 2; i <= n; i++) + { + prime.push_back(i); + } + + // 2. Пусть переменная p равна первому простому числу в массиве. + int p = prime[0]; + + // 3. Зачеркиваем числа, кратные p + step_3: + for (int i = 0; i < prime.size(); i++) + { + if (prime[i] == p) + { + continue; + } + if (prime[i] % p == 0) + { + prime.erase(prime.begin() + i); + i--; + } + } + + // 4. Найти первое не зачеркнутое число больше p + for (int i = 0; i < prime.size(); i++) + { + if (prime[i] > p) + { + p = prime[i]; + goto step_3; + } + } + + return prime; +} + diff --git a/task1.cpp b/task1.cpp new file mode 100644 index 0000000..03b8f9f --- /dev/null +++ b/task1.cpp @@ -0,0 +1,56 @@ +/* Задание 1 + * Написать программу для поиска наибольшего общего делителя (числа + * вводятся с клавиатуры после запуска программы): + * Нечетные варианты: наибольший делитель трех чисел методом деления + * (для поиска остатка отделения в языке C++ используется операция %) + * Четные варианты: наибольший общий делитель четырех чисел метолом + * вычитания + */ + +#include + +// Функция для нахождения НОД двух чисел (метод деления) +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); +} + +int main() +{ + int w, x, y, z; + + std::setlocale(LC_ALL, "Russian"); + std::cout << "Введите четыре числа: "; + std::cin >> w >> x >> y >> z; + + std::cout << "Найдем НОД чисел x, y, z: " << gcdOfThreeNumbers(x, y, z) << std::endl; + std::cout << "Найдем НОД чисел w, x, y, z: " << gcdOfFourNumbers(w, x, y, z) << std::endl; + + return 0; +} diff --git a/task2.cpp b/task2.cpp new file mode 100644 index 0000000..45778eb --- /dev/null +++ b/task2.cpp @@ -0,0 +1,46 @@ +/* + * Задание 2 + * Написать программу для факторизации заданного с клавиатуры числа + * методом простого перебора (указать простые множители и их кратность). + * Для анализа числа на простоту использовать решето Эратосфена/ + */ + +#include +#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; +} + +int main() +{ + int n; + std::cin >> n; + + auto factors = factorize(n); + + for (const auto& factor : factors) { + std::cout << factor.first << " : " << factor.second << "\n"; + } + + return 0; +} + diff --git a/task3.cpp b/task3.cpp new file mode 100644 index 0000000..e6223d5 --- /dev/null +++ b/task3.cpp @@ -0,0 +1,65 @@ +/* + * Задание 3 + * Написать программу для факторизации заданного с клавиатуры нечетного + * числа методом Ферма (указать простые множители и их кратность). Для + * анализа числа на простоту использовать решето Эратосфена + */ + +#include +#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; +} + +int main() +{ + int n; + std::cin >> n; + + auto factors = fermatFactorize(n); + + for (const auto& factor : factors) { + std::cout << factor.first << " : " << factor.second << "\n"; + } + + return 0; +} + diff --git a/task4.cpp b/task4.cpp new file mode 100644 index 0000000..839e875 --- /dev/null +++ b/task4.cpp @@ -0,0 +1,61 @@ +/* + * Задание 4 + * Написать программу для проверки на простоту числа Мерсенна с + * использование теста Люка-Лемера. С клавиатуры вводится номер числа + * Мерсенна + */ + +#include +#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; +} + +int main() { + int p; + std::cout << "Введите номер числа Мерсенна (простое число p): "; + std::cin >> p; + + // Проверка, является ли p простым + if (!isPrime(p)) { + std::cout << p << " не является простым числом." << std::endl; + return 1; + } + + // Проверка простоты числа Мерсенна + if (lucasLehmerTest(p)) { + std::cout << "Число Мерсенна M_" << p << " = 2^" << p << " - 1 является простым." << std::endl; + } else { + std::cout << "Число Мерсенна M_" << p << " = 2^" << p << " - 1 не является простым." << std::endl; + } + + return 0; +} + diff --git a/task5.cpp b/task5.cpp new file mode 100644 index 0000000..c4c24d4 --- /dev/null +++ b/task5.cpp @@ -0,0 +1,42 @@ +/* + * Написать программу для генерации последовательности + * из 10 пятизначных чисел фон Неймана + */ + +#include +#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; +} + +int main() +{ + unsigned long int n; + std::cin >> n; //>=10000 + + auto sequence = vonNeumannSequence(n); + + for (const auto& number : sequence) { + std::cout << number << " "; + } + + return 0; +} diff --git a/task6.cpp b/task6.cpp new file mode 100644 index 0000000..fe2131a --- /dev/null +++ b/task6.cpp @@ -0,0 +1,32 @@ +#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 << " "; + } +} + +int main() +{ + setlocale(LC_ALL, "Rus"); + int N, i, j; + bool A[1000]; + std::cout << "N > "; std::cin >> N; + std::cout << "Простые числа: 2 "; + Sundaram(A, N); +}