POJ - 2947 Widget Factory(同餘式的高斯消元)
阿新 • • 發佈:2018-12-13
ACCode:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 310; int mod; int Equ, Var; //方程式的個數, 未知數的個數 int A[maxn][maxn]; //增廣矩陣,最後一列是係數 int X[maxn]; //儲存所有的解 bool FreeX[maxn]; int FreeNum; //自由元的個數 int GCD(int a, int b) { if(b == 0) return a; else return GCD(b, a%b); } int LCM(int a, int b) { return a/GCD(a, b) * b; } void ex_gcd(int a, int b, int& d, int& x, int& y) //擴充套件歐幾里得求貝祖等式 { if(!b){ d = a; x = 1; y = 0; } else{ ex_gcd(b, a%b, d, y, x); y -= x*(a/b); } } //高斯消元主方程 int Gauss_Elimination() { int i, j, k; int MaxRow; int col = 0; int Lcm; int ta, tb; int temp; int FreeXNum, FreeIndex; for(int i = 0; i < Var; i++){ X[i] = 0; FreeX[i] = true; } for(k = 0; k < Equ && col < Var; k++, col++){ MaxRow = k; for(i = k+1; i < Equ; i++){ if(abs(A[i][col]) > abs(A[MaxRow][col])) MaxRow = i; } if(MaxRow != k){ for(j = k; j <= Var; j++) swap(A[k][j], A[MaxRow][j]); } if(A[k][col] == 0){ k --; continue; } for(i = k+1; i < Equ; i++){ if(A[i][col]){ Lcm = LCM(abs(A[i][col]), abs(A[k][col])); ta = Lcm / abs(A[i][col]); tb = Lcm / abs(A[k][col]); if(A[i][col] * A[k][col] < 0) tb = -tb; for(j = col; j <= Var; j++) A[i][j] = (A[i][j]*ta%mod - A[k][j]*tb%mod + mod) % mod; } } } //已經化成階梯型矩陣了 for(i = k; i < Equ; i++) if(A[i][col]) return -1; //存在 0 0 0 3 這樣的情況,無解 if(k < Var) //存在 0 0 0 0 這樣的情況,有多解 return Var-k; //返回自由元的個數 // 回代 for(int i = Var-1; i >= 0; i--){ for(int j = i+1; j < Var; j++){ A[i][Var] -= ((X[j] * A[i][j]) % mod); } A[i][Var] = (A[i][Var]%mod + mod) % mod; int x, y, d; ex_gcd(A[i][i], mod, d, x, y); X[i] = (A[i][Var]*x% mod + mod) % mod; } return 0; } char Wed[7][5] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN" }; int get_id(char *str) { for(int i = 0; i < 7; i++) if(!strcmp(Wed[i], str)) return i; } int main() { int num, dur, x; char s1[50], s2[50]; while(scanf("%d %d", &Var, &Equ) && (Var+Equ)){ memset(A, 0, sizeof(A)); mod = 7; for(int i = 0; i < Equ; i++){ scanf("%d %s %s", &num, s1, s2); int be = get_id(s1), ed = get_id(s2); if(be > ed) dur = ed + mod+1 - be; else dur = ed - be + 1; A[i][Var] = dur; while(num--){ scanf("%d", &x); A[i][x-1] ++; A[i][x-1] %= mod; } } int ans = Gauss_Elimination(); if(ans == -1) cout << "Inconsistent data." << endl; else if(ans > 0) cout << "Multiple solutions." << endl; else { for(int i = 0; i < Var; i++){ if(X[i] < 3) X[i] += mod; if(X[i] > 9){ X[i] %= 7; if(X[i] < 3) X[i] += mod; } if(i == 0) cout << X[i]; else cout << " " << X[i]; } cout << endl; } } return 0; }