TIOJ-1157

1947年美國勞動統計局花了兩年的時間,收集超過250,000經濟資訊。兩年後哈佛大學Wassily Leontief教授將這些經濟活動分析成500產業,其中包括煤業、汽車業、運輸業等。對每一個產業,Leontief教授用一個線性方程式來表達這個產業如何將其產出分散或影響其他的產業。他的研究開啟了日後利用電腦來解決大型數學問題的先例。Leontief教授後來在1973年獲得諾貝爾經濟貢獻奬。
由於在科學或經濟上所包含的資料都相當多,有很多數學模式都是線性的,所以線性系統求解可以說是相當重要。有關線性系統的解法可以應用高斯消去法(Gauss-Jordan Elimination) 來求解。
(以下略)

$n<50<b$

第一行為0或1或N分別表示無解、1組解、及無限多組解


前幾天看了一陣子的高斯消去,數學不好沒辦法><
然後就來寫裸題了
輸出分數的部分我不想讓code變太髒於是決定統一用運算子重載
複雜度$\mathcal{O}(n^3logn)$($logn$來自約分)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <bits/stdc++.h>
using namespace std;
typedef pair<long long, long long> pll;
typedef long long ll;
#define S second
#define F first
#define mp make_pair
pll operator-(const pll &a, const pll &b) {
ll g = b.S/__gcd(abs(a.S), b.S)*a.S;
ll x = a.F*g/a.S-b.F*g/b.S, y = g;
g = __gcd(abs(x), y);
return mp(x/g, y/g);
}
pll operator*(const pll &a, const pll &b) {
ll x = a.F*b.F;
ll y = a.S*b.S;
if(y < 0) y*=-1, x*=-1;
ll g = __gcd(abs(x), y);
return mp(x/g, y/g);
}
ostream &operator<<(ostream &out, const pll &a) {
if(a.S == 1)
out << a.F;
else
out << a.F << '/' << a.S;
return out;
}
pll operator/(const pll &a, const pll &b) {
ll x = a.F*b.S;
ll y = a.S*b.F;
if(y < 0) y*=-1, x*=-1;
ll g = __gcd(abs(x), y);
return mp(x/g, y/g);
}

signed main() {
ios::sync_with_stdio(0); cin.tie(0);

int n;
cin >> n;
vector<vector<pll>> arr(n, vector<pll>(n+1));

for(int i = 0; i < n; i++)
for(int j = 0, a; j < n+1; j++)
cin >> a, arr[i][j]=mp(a, 1);

for(int i = 0; i < n; i++) {
bool can = 0;
for(int j = i; j < n; j++) {
if(arr[j][i].F != 0) {
if(i!=j)
swap(arr[i], arr[j]);
can = 1;
break;
}
}
if(!can) {
continue;
}
for(int j = 0; j < n; j++) {
if(i == j)
continue;
auto x = arr[j][i]/arr[i][i];
for(int k = 0; k < n+1; k++)
arr[j][k] = (arr[j][k]-(arr[i][k]*x));
}
}

for(int i = 0; i < n; i++) {
bool can = 0;
for(int j = 0; j < n; j++)
can|=arr[i][j].F;
if(!can) {
if(arr[i][n].F)
return cout << '0', 0;
else
return cout << 'N', 0;
}
}
for(int i = 0; i < n; i++) {
if(!arr[i][i].F)
return cout << 'N', 0;
}

cout << "1\n";
for(int i = 0; i < n; i++) {
cout << 'x' << i+1 << " = " << arr[i][n]/arr[i][i] << '\n';
}

return 0;
}