高斯消元:
事实上就是用矩阵初等变换解线性方程组,仅仅是他要求每次选取的主元一定要是最大值。
模板
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; const int MAXN=10000; int a[MAXN][MAXN];//增广矩阵 int x[MAXN];//解集 bool free_x[MAXN];//标记是否是不确定的变元 int gcd(int a,int b) {//最大公约数 int t; while(b!=0) { t=b; b=a%b; a=t; } return a; } int lcm(int a,int b) {//求最小公倍数 return a/gcd(a,b)*b;//先除后乘防溢出 } int Gauss(int equ,int var) { int i,j,k; int max_r;// 当前这列绝对值最大的行. int col;//当前处理的列 int ta,tb; int LCM,temp,free_x_num,free_index; for(int i=0; i<=var; i++) { //初始化 x[i]=0; free_x[i]=true; } //转换为行阶梯阵. col=0; // 当前处理的列 k为当前处理的行 for(k = 0; k < equ && col < var; k++,col++) { //最后一列没有化解 //找到该col列元素绝对值最大的那行与第k行交换(为了在除法时减小误差) max_r=k; for(i=k+1; i<equ; i++) { if(abs(a[i][col])>abs(a[max_r][col])) max_r=i; } if(max_r!=k) { //与第k行交换. for(j=k; j<var+1; j++) swap(a[k][j],a[max_r][j]); } if(a[k][col]==0) { //说明该col列第k行下面全是0了,则处理当前行的下一列. k--; continue; } for(i=k+1; i<equ; i++) { // 利用主元消元 if(a[i][col]!=0) { 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+1; j++) a[i][j] = a[i][j]*ta-a[k][j]*tb; } } } // 1. 无解的情况有:0=d; for (i = k; i < equ; i++) if (a[i][col] != 0) return -1; // 2. 无穷解的情况 if (k < var) { //var是未知元个数。首先,自由变元有var - k个 for (i = k - 1; i >= 0; i--) { free_x_num = 0; for (j = 0; j < var; j++) if (a[i][j] != 0 && free_x[j]) free_x_num++; free_index = j; if (free_x_num > 1) continue; // 无法求解出确定的变元. // 说明就仅仅有一个不确定的变元free_index。那么能够求解出该变元,且该变元是确定的. temp = a[i][var]; for (j = 0; j < var; j++) { //找已经求出的未知元 if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j];//移项 }// 求出该变元. x[free_index] = temp / a[i][free_index]; free_x[free_index] = 0; // 该变元是确定的. } return var - k; // 自由变元有var - k个. } // 唯一解的情况:在var*(var + 1)的增广阵中形成严格的上三角阵. // 计算出Xn-1, Xn-2 ... X0. for (i=var-1; i>=0; i--) { temp=a[i][var]; for (j = i + 1; j < var; j++) { if (a[i][j] != 0) temp -= a[i][j] * x[j]; } if (temp % a[i][i] != 0) return -2; // 说明有浮点数解,但无整数解. x[i] = temp / a[i][i]; } return 0; } int main() { int i, j; int equ,var;//行,列 while (scanf("%d %d", &equ, &var) != EOF) { memset(a, 0, sizeof(a)); for (i = 0; i < equ; i++) { for (j = 0; j < var + 1; j++) { //增广矩阵 scanf("%d", &a[i][j]); } } int free_num = Gauss(equ,var); } return 0; }