728x90
반응형
12020번: LU 분해
문제
https://www.acmicpc.net/problem/12020
12020번: LU 분해
\(N \times N\) Matrix A가 주어진다. LU 분해란 \(A = LU\)꼴의 Matrix 곱로 분해하는 것이다. (단, \(L\)은 Lower Triangular Matrix, \(U\)는 Upper Triangular Matrix) Lower Triangular Matrix란 \(L_{ij} = 0 \text{ (if }i < j\text{)}\) Upper
www.acmicpc.net
풀이
선형대수학에서 배우는 LU 분해를 구현하는 문제다. 구현 자체는 LU 분해를 하는 방식대로 하면 된다. LU 분해에 대해선 설명 잘해놓은 다른 블로그를 참고하는 게 좋을 것 같다. 코드에 대한 설명은 아래 코드에 주석으로 설명해 놓았다.
문제에서 신경 써야 할 부분은 LU 분해를 할 수 없는 경우에 대한 예외 처리다. 이것 때문에 구글링을 해봤고, LU 분해를 할 수 없는 테스트 케이스를 찾았다.
3
1 0 0
0 0 2
0 -1 1
이 테스트 케이스를 실행해 보니 일부 원소가 nan과 inf으로 출력되었다. nan은 0/0, inf는 양의 무한대, -inf는 음의 무한대였다. 모두 0에 의해 생긴 것이므로 nan에 대한 예외처리를 하면 inf도 해결될 것이라고 생각했다. 구글링을 통해 isnan 함수를 알게 되었고 L, U 행렬 전체에서 nan이 있다면 -1을 출력하고 종료하도록 했다.
코드
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int n;
vector<vector<double>> L(1001, vector<double>(1001, 0)), U(1001, vector<double>(1001, 0));
cin >> n;
// U행렬은 일반행렬을 입력받아 U행렬로 변경
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
cin >> U[i][j];
// L은 단위행렬
L[i][j] = i == j ? 1 : 0;
}
// LU 분해
for (int i = 0; i < n - 1; i++) {
// 대각행렬 원소
double d = U[i][i];
// 다음 모든 행
for (int j = i + 1; j < n; j++) {
// 첫 번째 원소
double x = U[j][i] / d;
// 행의 각 열에 첫 번째 원소가 0이 되도록 뺀다
for (int k = 0; k < n; k++)
U[j][k] -= x * U[i][k];
// L 행렬
L[j][i] = x;
}
}
// LU 분해를 할 수 없는 경우
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
// L 또는 U에 수가 아닌 것이 있는 경우
if (isnan(L[i][j]) || isnan(U[i][j])) {
cout << "-1\n";
return 0;
}
// 소수 4째자리에서 반올림하여 3째자리까지 출력
cout.precision(3);
cout << fixed;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
cout << L[i][j] << ' ';
cout << '\n';
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
cout << U[i][j] << ' ';
cout << '\n';
}
return 0;
}
728x90
반응형
'Problem Solving > BOJ' 카테고리의 다른 글
[백준 / BOJ] C++ 1436 영화감독 숌 (0) | 2023.03.04 |
---|---|
[백준 / BOJ] C++ 27648 증가 배열 만들기 (0) | 2023.03.04 |
[백준 / BOJ] C++ 4179 불! (0) | 2023.03.03 |
[백준 / BOJ] C++ 5719 거의 최단 경로 (0) | 2023.03.03 |
[백준 / BOJ] C++ 1188 음식 평론가 (0) | 2023.03.03 |