Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fstream>
- #include <cstdlib>
- #include <cstdio>
- #include <string>
- #include <vector>
- // сишный стиль для упрощения вывода незначащих нулей для ячеек, кроме поседней
- typedef std::vector<int> lnum; // вектор интов становится типом лнам
- const int base = 1000 * 1000 * 1000; // сколько цифр в одной ячейке
- void print(lnum a) { // функция вывода
- bool flag = false; //это флаг для вывода самой последней ячейки
- FILE *fout = fopen("output.txt", "a"); // открыти файла на запись
- for (int i = a.size() - 1; i >= 0; i--)
- if ((a[i] != 0) || (a[i] == 0 && flag == 1)) { // проверка, является ли наша ячейка последней
- if (flag == 0) {
- flag = true;
- fprintf(fout, "%d", a[i]); // вывод ячейки, д - это число
- } else
- fprintf(fout, "%09d", a[i]); // вывод незначащих нулей в ячейке
- }
- }
- lnum toVec(std::string &str) { // преобразование строки в длинное число
- lnum toReturn; // переменная для возращаемого числа
- for (int i = (int) str.length(); i > 0; i -= 9)
- if (i < 9)
- toReturn.push_back(atoi(str.substr(0, i).c_str())); // если менше 9, то заполняем от 0 дл i число
- else
- toReturn.push_back(atoi(str.substr(i - 9, 9).c_str())); // заполняем зеркално
- return toReturn;
- }
- lnum multiply(lnum a, lnum b) { // умножение длинных чисел
- lnum c(a.size() + b.size()); // число длинной, равной сумме длин двух умножаемых чисел
- for (size_t i = 0; i < a.size(); ++i)
- for (int j = 0, carry = 0; j < (int) b.size() || carry; ++j) { // ВАЖНО, т.к у нас условие с ИЛИ,
- // то наш итератор для второго числа может быть больше длины второго числа, поэтому строкой ниже
- // в тернарке мы проверяем вышли ли мы за длину Б, и если вышли, то домножаем на 0,
- // чтобы не выйти за пределы массива и добавляем туда остаток от предудыщего деления,
- // и получаем текущее число, с которым работаем ниже
- long long cur = c[i + j] + a[i] * 1ll * (j < (int) b.size() ? b[j] : 0) + carry;
- c[i + j] = int(cur % base); // закидываем в ячейку нового числа текущее число, мод деления на основание
- carry = int(cur / base); // записываем в остаток деленное текущее число на основание
- }
- while (c.size() > 1 && c.back() == 0) // удаляем незначащие нули
- c.pop_back();
- return c;
- }
- lnum doubleFact(int n) { // нахождение двойного факториала
- std::string one = "1";
- lnum res = toVec(one); // в лнаме по умолчанию лежит единичка
- for (int i = n; i >= 2; i -= 2) { // проходим циклом от н до нуля с шагом 2, чтобы четные оставались четными,
- // а нечетные нечетными
- std::string toMultiply = std::to_string(i); // конвентируем в строку итератор
- lnum toMult = toVec(toMultiply); // создаем лнам, равный итератору, используя переменную строкового типа выше
- res = multiply(res, toMult); // перемножаем число с предыдущего шага (или 1 при первой итерации) и итератор
- }
- return res;
- }
- int main() {
- using namespace std;
- ifstream cin("input.txt");
- ofstream cout("output.txt");
- int n;
- cin >> n;
- lnum result = doubleFact(n);
- print(result);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement