Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <iomanip>
- #include <cmath>
- #include <stdexcept>
- using namespace std;
- // Функция для выделения памяти под матрицу
- double** allocate_matrix(int n, int m) {
- double** matrix = new double* [n];
- for (int i = 0; i < n; ++i) {
- matrix[i] = new double[m];
- }
- return matrix;
- }
- // Функция для освобождения памяти матрицы
- void free_matrix(double** matrix, int n) {
- for (int i = 0; i < n; ++i) {
- delete[] matrix[i];
- }
- delete[] matrix;
- }
- // Функция вывода корней
- void output_roots(double* roots, int n) {
- for (int i = 0; i < n; ++i) {
- cout << fixed << setprecision(6) << roots[i];
- if (i < n - 1) cout << " ";
- }
- cout << endl;
- }
- // Функция для вычисления определителя матрицы
- double determinant(double** matrix, int n) {
- double det = 1.0;
- // Создаем временную матрицу для вычислений
- double** temp = allocate_matrix(n, n);
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < n; ++j) {
- temp[i][j] = matrix[i][j];
- }
- }
- // Приводим матрицу к верхнетреугольному виду
- for (int col = 0; col < n; ++col) {
- // Поиск ведущего элемента
- int max_row = col;
- for (int i = col + 1; i < n; ++i) {
- if (fabs(temp[i][col]) > fabs(temp[max_row][col])) {
- max_row = i;
- }
- }
- // Перестановка строк
- if (max_row != col) {
- for (int j = col; j < n; ++j) {
- swap(temp[col][j], temp[max_row][j]);
- }
- det *= -1; // При перестановке строк определитель меняет знак
- }
- // Если ведущий элемент нулевой, то определитель равен 0
- if (fabs(temp[col][col]) < 1e-10) {
- free_matrix(temp, n);
- return 0.0;
- }
- // Исключение переменной из других уравнений
- for (int i = col + 1; i < n; ++i) {
- double factor = temp[i][col] / temp[col][col];
- for (int j = col; j < n; ++j) {
- temp[i][j] -= temp[col][j] * factor;
- }
- }
- }
- // Вычисление определителя как произведения диагональных элементов
- for (int i = 0; i < n; ++i) {
- det *= temp[i][i];
- }
- free_matrix(temp, n);
- return det;
- }
- // Функция решения СЛАУ методом Крамера
- int cramer(double** matrix, int n, int m, double* roots) {
- // Проверка на квадратную матрицу коэффициентов
- if (m != n + 1) {
- return 0;
- }
- // Создаем матрицу коэффициентов (без столбца свободных членов)
- double** A = allocate_matrix(n, n);
- double* B = new double[n];
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < n; ++j) {
- A[i][j] = matrix[i][j];
- }
- B[i] = matrix[i][n];
- }
- // Вычисляем определитель основной матрицы
- double det_A = determinant(A, n);
- // Если определитель равен нулю, система либо не имеет решений, либо имеет бесконечно много
- if (fabs(det_A) < 1e-10) {
- free_matrix(A, n);
- delete[] B;
- return 0;
- }
- // Создаем временную матрицу для вычисления определителей
- double** temp = allocate_matrix(n, n);
- // Вычисляем корни по формулам Крамера
- for (int col = 0; col < n; ++col) {
- // Копируем матрицу A в temp
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < n; ++j) {
- temp[i][j] = A[i][j];
- }
- }
- // Заменяем колонку col на столбец свободных членов
- for (int i = 0; i < n; ++i) {
- temp[i][col] = B[i];
- }
- // Вычисляем определитель измененной матрицы
- double det_temp = determinant(temp, n);
- // Вычисляем корень
- roots[col] = det_temp / det_A;
- }
- free_matrix(A, n);
- free_matrix(temp, n);
- delete[] B;
- return 1;
- }
- int main() {
- int n, m;
- double** matrix = nullptr;
- double* roots = nullptr;
- try {
- cin >> n >> m;
- if (n <= 0 || m <= 0 || m != n + 1) {
- throw runtime_error("Invalid input");
- }
- matrix = allocate_matrix(n, m);
- roots = new double[n];
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < m; ++j) {
- cin >> matrix[i][j];
- }
- }
- if (cramer(matrix, n, m, roots)) {
- output_roots(roots, n);
- }
- else {
- cout << "n/a" << endl;
- }
- }
- catch (...) {
- cout << "n/a" << endl;
- }
- if (matrix) free_matrix(matrix, n);
- if (roots) delete[] roots;
- return 0;
- }
- Входные данные
- 3 4
- 1 1 1 2
- 4 5 3 7
- 2 7 7 9
- Выходные данные
- 1.000000 0.000000 1.000000
Advertisement
Add Comment
Please, Sign In to add comment