POJ2947 高斯消元 xingxing在努力
这道题可以抽象成k1*x1+k2*x2+k3*x3+...+kn*xn = y (mod 7), 列很多这样的方程, 使用高斯消元法解就行。注意高斯消元一般和同余方程联系在一起, 所以在构造增广矩阵的时候应该给所有元素(a%mod+mod)%mod, 在高斯消元的过程中也不应该落下,代码如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int maxn = 300 + 10; int a[maxn][maxn]; int n, m; //m个方程 n个变量 void debug() { printf("debug-------------\n"); for(int i=0; i<m; i++) { for(int j=0; j<=n; j++) printf("%d ", a[i][j]); printf("\n"); } } int getnum(char s[]) { if(s[2]=='N' && s[0]=='M') return 0; else if(s[2]=='E') return 1; else if(s[2]=='D') return 2; else if(s[2]=='U') return 3; else if(s[2]=='I') return 4; else if(s[2]=='T') return 5; else if(s[2]=='N'&&s[0]=='S') return 6; return -1; } int gcd(int n, int m) { return m==0? n:gcd(m, n%m); } int lcm(int n, int m) { return n/gcd(n, m)*m; } int equ, var; //equ个方程 var个变量 int ans[maxn]; //解空间 int free_x[maxn], free_num; int gauss() { free_num = 0; int k, col; for(k=0,col=0; k<equ&&col<var; k++,col++) { //处理第k个方程第col个变量 int max_r = k; for(int i=k+1; i<equ; i++) { if(abs(a[i][col])>abs(a[max_r][col])) max_r = i; } if(max_r != k) //交换第k行和第max_r行 for(int j=k; j<=var; j++) swap(a[k][j], a[max_r][j]); if(a[k][col] == 0) { k--; free_x[free_num++] = col; continue; } for(int i=k+1; i<equ; i++) //用第k个方程消第i个方程 { if(a[i][col] == 0) continue; int LCM = lcm(a[k][col], a[i][col]); int ta = LCM/a[k][col]; int tb = LCM/a[i][col]; for(int j=col; j<=var; j++) { a[i][j] = a[i][j]*tb - a[k][j]*ta; a[i][j] = (a[i][j]%7+7)%7; ////////////// 这个一定要加 } } } //debug(); for(int i=k; i<equ; i++) if(a[i][col] != 0) return -1; if(k < n) return -2; for(int i=k-1; i>=0; i--) //逐个处理方程 { int tmp = a[i][var]; for(int j=i+1; j<var; j++) tmp = (tmp-ans[j]*a[i][j])%7; //这里也要处理 while(tmp%a[i][i] != 0) //偷懒了 tmp += 7; ans[i] = tmp/a[i][i]; while(ans[i] < 3) ans[i]+=7; while(ans[i]>9) ans[i]-=7; } return 1; } int main() { //freopen("in.txt", "r", stdin); while(scanf("%d%d", &n, &m)==2) { if(n==0&&m==0) break; memset(a, 0, sizeof(a)); //开始构造增广矩阵 for(int i=0; i<m; i++) { int t; char s1[10], s2[10]; scanf("%d%s%s", &t, s1, s2); a[i][n] = getnum(s2)-getnum(s1)+1; a[i][n] = (a[i][n]%7 + 7)%7; //这个也不能落下 if(a[i][n]==0) a[i][n] = 7; for(int j=0; j<t; j++) { int tp; scanf("%d", &tp); a[i][tp-1]++; a[i][tp-1] = (a[i][tp-1]%7 + 7)%7; //同样这里要处理 } } //debug(); equ = m; var = n; int flog = gauss(); if(flog == -1) printf("Inconsistent data.\n"); else if(flog == -2) printf("Multiple solutions.\n"); else { for(int i=0; i<n; i++) printf("%d%c", ans[i], i==n-1?'\n':' '); } } return 0; }

浙公网安备 33010602011771号