commit d45769c4bcd0c27a4c142b07b27bd563393a9444 Author: Nikolai Papin Date: Sat Oct 26 09:11:25 2024 +0300 First commit 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); +}