RobertDeMilo

СЛАУ Крамер

Jul 26th, 2025 (edited)
535
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.57 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <cmath>
  4. #include <stdexcept>
  5.  
  6. using namespace std;
  7.  
  8. // Функция для выделения памяти под матрицу
  9. double** allocate_matrix(int n, int m) {
  10.     double** matrix = new double* [n];
  11.     for (int i = 0; i < n; ++i) {
  12.         matrix[i] = new double[m];
  13.     }
  14.     return matrix;
  15. }
  16.  
  17. // Функция для освобождения памяти матрицы
  18. void free_matrix(double** matrix, int n) {
  19.     for (int i = 0; i < n; ++i) {
  20.         delete[] matrix[i];
  21.     }
  22.     delete[] matrix;
  23. }
  24.  
  25. // Функция вывода корней
  26. void output_roots(double* roots, int n) {
  27.     for (int i = 0; i < n; ++i) {
  28.         cout << fixed << setprecision(6) << roots[i];
  29.         if (i < n - 1) cout << " ";
  30.     }
  31.     cout << endl;
  32. }
  33.  
  34. // Функция для вычисления определителя матрицы
  35. double determinant(double** matrix, int n) {
  36.     double det = 1.0;
  37.  
  38.     // Создаем временную матрицу для вычислений
  39.     double** temp = allocate_matrix(n, n);
  40.     for (int i = 0; i < n; ++i) {
  41.         for (int j = 0; j < n; ++j) {
  42.             temp[i][j] = matrix[i][j];
  43.         }
  44.     }
  45.  
  46.     // Приводим матрицу к верхнетреугольному виду
  47.     for (int col = 0; col < n; ++col) {
  48.         // Поиск ведущего элемента
  49.         int max_row = col;
  50.         for (int i = col + 1; i < n; ++i) {
  51.             if (fabs(temp[i][col]) > fabs(temp[max_row][col])) {
  52.                 max_row = i;
  53.             }
  54.         }
  55.  
  56.         // Перестановка строк
  57.         if (max_row != col) {
  58.             for (int j = col; j < n; ++j) {
  59.                 swap(temp[col][j], temp[max_row][j]);
  60.             }
  61.             det *= -1; // При перестановке строк определитель меняет знак
  62.         }
  63.  
  64.         // Если ведущий элемент нулевой, то определитель равен 0
  65.         if (fabs(temp[col][col]) < 1e-10) {
  66.             free_matrix(temp, n);
  67.             return 0.0;
  68.         }
  69.  
  70.         // Исключение переменной из других уравнений
  71.         for (int i = col + 1; i < n; ++i) {
  72.             double factor = temp[i][col] / temp[col][col];
  73.             for (int j = col; j < n; ++j) {
  74.                 temp[i][j] -= temp[col][j] * factor;
  75.             }
  76.         }
  77.     }
  78.  
  79.     // Вычисление определителя как произведения диагональных элементов
  80.     for (int i = 0; i < n; ++i) {
  81.         det *= temp[i][i];
  82.     }
  83.  
  84.     free_matrix(temp, n);
  85.     return det;
  86. }
  87.  
  88. // Функция решения СЛАУ методом Крамера
  89. int cramer(double** matrix, int n, int m, double* roots) {
  90.     // Проверка на квадратную матрицу коэффициентов
  91.     if (m != n + 1) {
  92.         return 0;
  93.     }
  94.  
  95.     // Создаем матрицу коэффициентов (без столбца свободных членов)
  96.     double** A = allocate_matrix(n, n);
  97.     double* B = new double[n];
  98.  
  99.     for (int i = 0; i < n; ++i) {
  100.         for (int j = 0; j < n; ++j) {
  101.             A[i][j] = matrix[i][j];
  102.         }
  103.         B[i] = matrix[i][n];
  104.     }
  105.  
  106.     // Вычисляем определитель основной матрицы
  107.     double det_A = determinant(A, n);
  108.  
  109.     // Если определитель равен нулю, система либо не имеет решений, либо имеет бесконечно много
  110.     if (fabs(det_A) < 1e-10) {
  111.         free_matrix(A, n);
  112.         delete[] B;
  113.         return 0;
  114.     }
  115.  
  116.     // Создаем временную матрицу для вычисления определителей
  117.     double** temp = allocate_matrix(n, n);
  118.  
  119.     // Вычисляем корни по формулам Крамера
  120.     for (int col = 0; col < n; ++col) {
  121.         // Копируем матрицу A в temp
  122.         for (int i = 0; i < n; ++i) {
  123.             for (int j = 0; j < n; ++j) {
  124.                 temp[i][j] = A[i][j];
  125.             }
  126.         }
  127.  
  128.         // Заменяем колонку col на столбец свободных членов
  129.         for (int i = 0; i < n; ++i) {
  130.             temp[i][col] = B[i];
  131.         }
  132.  
  133.         // Вычисляем определитель измененной матрицы
  134.         double det_temp = determinant(temp, n);
  135.  
  136.         // Вычисляем корень
  137.         roots[col] = det_temp / det_A;
  138.     }
  139.  
  140.     free_matrix(A, n);
  141.     free_matrix(temp, n);
  142.     delete[] B;
  143.  
  144.     return 1;
  145. }
  146.  
  147. int main() {
  148.     int n, m;
  149.     double** matrix = nullptr;
  150.     double* roots = nullptr;
  151.  
  152.     try {
  153.         cin >> n >> m;
  154.         if (n <= 0 || m <= 0 || m != n + 1) {
  155.             throw runtime_error("Invalid input");
  156.         }
  157.  
  158.         matrix = allocate_matrix(n, m);
  159.         roots = new double[n];
  160.  
  161.         for (int i = 0; i < n; ++i) {
  162.             for (int j = 0; j < m; ++j) {
  163.                 cin >> matrix[i][j];
  164.             }
  165.         }
  166.  
  167.         if (cramer(matrix, n, m, roots)) {
  168.             output_roots(roots, n);
  169.         }
  170.         else {
  171.             cout << "n/a" << endl;
  172.         }
  173.     }
  174.     catch (...) {
  175.         cout << "n/a" << endl;
  176.     }
  177.  
  178.     if (matrix) free_matrix(matrix, n);
  179.     if (roots) delete[] roots;
  180.  
  181.     return 0;
  182. }
  183.  
  184. Входные данные
  185. 3 4
  186. 1 1 1 2
  187. 4 5 3 7
  188. 2 7 7 9
  189. Выходные данные
  190. 1.000000 0.000000 1.000000
Advertisement
Add Comment
Please, Sign In to add comment