#include <stdio.h>
#include <stdlib.h>

void inputMatrix(int **matrix, int m, int n) {
    // Функция для ввода матрицы размером m x n
    printf("Введите элементы матрицы %dx%d:\n", m, n);
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            printf("Элемент [%d][%d]: ", i, j);
            scanf("%d", &matrix[i][j]); // Считываем элемент матрицы
        }
    }
}

void freeMatrix(int **matrix, int m) {
    // Функция для освобождения памяти, выделенной под матрицу
    for (int i = 0; i < m; i++) {
        free(matrix[i]);
    }
    free(matrix);
}

double determinant(int **matrix, int n) {
    // Функция для вычисления определителя матрицы
    if (n <= 0) {
        // Если размер матрицы неверный, выводим сообщение и возвращаем 0
        printf("Невозможно вычислить определитель для матрицы размером %dx%d\n", n, n);
        return 0;
    }
    if (n == 1) {
        return matrix[0][0]; // Определитель 1x1
    }
    if (n == 2) {
        // Определитель 2x2
        return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
    }
    
    double det = 0; // Переменная для хранения определителя
    for (int p = 0; p < n; p++) {
        // Создаем подматрицу
        int **subMatrix = (int **)malloc((n - 1) * sizeof(int *));
        for (int i = 0; i < n - 1; i++) {
            subMatrix[i] = (int *)malloc((n - 1) * sizeof(int));
        }
        
        for (int i = 1; i < n; i++) {
            int colIndex = 0;
            for (int j = 0; j < n; j++) {
                if (j == p) continue; // Пропускаем текущий столбец
                subMatrix[i - 1][colIndex] = matrix[i][j];
                colIndex++;
            }
        }

        // Рекурсивно вычисляем детерминант подматрицы
        det += (p % 2 == 0 ? 1 : -1) * matrix[0][p] * determinant(subMatrix, n - 1);
        
        freeMatrix(subMatrix, n - 1); // Освобождаем память под подматрицу
    }
    return det;
}

int main() {
    int m, n;

    // Считываем размеры матрицы
    printf("Введите количество строк (M): ");
    scanf("%d", &m);
    printf("Введите количество столбцов (N): ");
    scanf("%d", &n);

    // Проверка на возможность вычисления определителя
    if (m != n) {
        printf("Определитель может быть вычислен только для квадратной матрицы. Введите квадратную матрицу!\n");
        return 0;
    }

    // Выделяем память под матрицу
    int **matrix = (int **)malloc(m * sizeof(int *));
    for (int i = 0; i < m; i++) {
        matrix[i] = (int *)malloc(n * sizeof(int));
    }

    // Вводим матрицу
    inputMatrix(matrix, m, n);

    // Вычисляем определитель
    double det = determinant(matrix, n);
    if (det != 0) {
        printf("Определитель матрицы: %.2f\n", det);
    }

    // Освобождаем память
    freeMatrix(matrix, m);
    return 0;
}