1. 程式人生 > >[Luogu 3389]【模板】高斯消元法

[Luogu 3389]【模板】高斯消元法

code wke using 整數 mat inner math ews vpd

Description

給定一個線性方程組,對其求解

Input

第一行,一個正整數 n

第二至 n+1 行,每行 n+1 個整數,為a1,a2?an和 b,代表一組方程。1??,a?2???a?n?? 和 bbb,代表一組方程。

Output

共n行,每行一個數,第 i 行為 xi

如果不存在唯一解,在第一行輸出"No Solution".

Sample Input

3
1 3 4 5
1 4 7 3
9 3 2 2

Sample Output

-0.97
5.18
-2.39

HINT

技術分享

題解

矩陣變換:
一、交換變換:$R_i<->R_j$,表示將$R_i$與$R_j$的所有元素對應交換


二、倍法變換:$R_i=R_i*k$,表示將$R_i$行的所有元素都乘上一個常數$k$
三、消去變換:$R_i=R_i+R_j*k$,表示將$R_i$行的所有元素對應的加上$R_j$行元素的$k$倍
------------------------------------------------------------------
實數解直接加減消元
整數解消元的時候用最小公倍數消去目標系數
------------------------------------------------------------------
① 無解 當方程中出現$(0, 0, …, 0, a)$的形式,且$a != 0$時,說明是無解的。

② 唯一解 形成了嚴格的上三角陣
③ 無窮解 不能形成嚴格的上三角形

 1 //It is made by Awson on 2017.10.10
 2 #include <set>
 3 #include <map>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <cmath>
 7 #include <stack>
 8 #include <queue>
 9 #include <vector>
10 #include <string
> 11 #include <cstdio> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 #define LL long long 17 #define Min(a, b) ((a) < (b) ? (a) : (b)) 18 #define Max(a, b) ((a) > (b) ? (a) : (b)) 19 #define sqr(x) ((x)*(x)) 20 using namespace std; 21 const int N = 100; 22 23 int n; 24 double a[N+5][N+5]; 25 26 void Gauss() { 27 for (int line = 1; line <= n; line++) { 28 int Max_line = line; 29 for (int i = line+1; i <= n; i++) 30 if (fabs(a[i][line]) > fabs(a[Max_line][line])) 31 Max_line = i; 32 if (Max_line != line) swap(a[line], a[Max_line]); 33 if (a[line][line] == 0) { 34 printf("No Solution\n"); 35 return; 36 } 37 for (int i = line+1; i <= n; i++) { 38 double tmp = a[i][line]/a[line][line]; 39 for (int j = line; j <= n+1; j++) 40 a[i][j] -= a[line][j]*tmp; 41 } 42 } 43 for (int i = n; i >= 1; i--) { 44 for (int j = i+1; j <= n; j++) 45 a[i][n+1] -= a[j][n+1]*a[i][j]; 46 a[i][n+1] /= a[i][i]; 47 } 48 for (int i = 1; i <= n ;i++) 49 printf("%.2lf\n", a[i][n+1]); 50 } 51 void work() { 52 scanf("%d", &n); 53 for (int i = 1; i <= n; i++) 54 for (int j = 1; j <= n+1; j++) 55 scanf("%lf", &a[i][j]); 56 Gauss(); 57 } 58 int main() { 59 work(); 60 return 0; 61 }

[Luogu 3389]【模板】高斯消元法