高斯消元(模板)

从kuangbin大神学来的高斯消元的写法,认真的写了一遍

应该没错,待测试。。。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 #define MX 35
  4 
  5 int equ,var;        // equ 行方程 var 个未知数
  6 int mat[MX][MX];    // 增广矩阵
  7 bool free_x[MX];    //是否自由变元
  8 int x[MX];          // x 解
  9 
 10 void Debug(void)
 11 {
 12     int i, j;
 13     cout<<"<---Debug--->"<<endl;
 14     for (i = 0; i < equ; i++)
 15     {
 16         for (j = 0; j < var + 1; j++)
 17         {
 18             cout << mat[i][j] << " ";
 19         }
 20         cout << endl;
 21     }
 22     cout<<"<---Debug--->"<<endl;
 23 }
 24 
 25 int gcd(int a,int b)
 26 {
 27     return b==0?a:gcd(b,a%b);
 28 }
 29 int lcm(int a,int b)
 30 {
 31     return a/gcd(a,b)*b;
 32 }
 33 
 34 int Gauss(int equ,int var)
 35 {
 36     int i,j,k,col;
 37     for (k=0,col=0; k<equ && col <var ; k++,col++)
 38     {
 39         int m_index = k;
 40         for (i=k+1;i<equ;i++)
 41             if (abs(mat[i][col])>abs(mat[m_index][col])) m_index = i;
 42         if (m_index != k)
 43         {
 44             for (j=col;j<var+1;j++)
 45                 swap(mat[k][j],mat[m_index][j]);
 46         }
 47         if (mat[k][col]==0) // 说明这列下面全为 0
 48         {
 49             k--;
 50             continue;
 51         }
 52         for (i=k+1;i<equ;i++)
 53         {
 54             if (mat[i][col]==0) continue;
 55             int LCM = lcm( abs(mat[k][col]),abs(mat[i][col]) );
 56             int ta = LCM / abs(mat[k][col]);
 57             int tb = LCM / abs(mat[i][col]);
 58             if (mat[k][col]*mat[i][col]<0) ta=-ta;
 59             for (j=col;j<var+1;j++)
 60                 mat[i][j] = mat[i][j]*tb - mat[k][j]*ta;
 61         }
 62     }
 63     // 无解的情况 (0, 0, ..., a) (a!=0)
 64     for (i=k;i<equ;i++)
 65         if (mat[i][col]!=0) return -1;
 66     if (k<var) // 出现了 (0,0,0,0,...,0) 的行
 67     {
 68         for (i=0;i<var;i++) free_x[i]=1;
 69         int f_n,n_index;
 70         for (i=k-1;i>=0;i--)
 71         {
 72             f_n = 0;
 73             for (j=0;j<var;j++)
 74             {
 75                 if (mat[i][j]!=0&&free_x[j]) f_n++,n_index=j;
 76             }
 77             if (f_n>1) continue; //有大于 1 的不确定数,跳过
 78             int tmp = mat[i][var];
 79             for (j=0;j<var;j++)
 80                 if (!free_x[j])
 81                     tmp -= x[j]*mat[i][j];
 82             x[n_index] = tmp / mat[i][n_index];
 83             free_x[n_index]=0;
 84         }
 85         return var-k; //返回自由变元个数
 86     }
 87     for (i=var-1;i>=0;i--)
 88     {
 89         int tmp = mat[i][var];
 90         for (j=i+1;j<var;j++)
 91             tmp -= mat[i][j]*x[i];
 92         if (tmp%mat[i][i]!=0) return -2;
 93         x[i]=tmp%mat[i][i];
 94     }
 95     return 0;
 96 }
 97 
 98 int main()
 99 {
100     while (~scanf("%d%d",&equ,&var)!=EOF)
101     {
102         for (int i=0;i<equ;i++)
103         for (int j=0;j<var+1;j++)
104                 scanf("%d",&mat[i][j]);
105         int ret = Gauss(equ,var);
106         if (ret == -1)
107         {
108             printf("无解\n");
109         }
110         else if (ret == -2)
111         {
112             printf("无整数解\n");
113         }
114         else if (ret == 0)
115         {
116             printf("有唯一解(如下):\n");
117             for (int i=0;i<var;i++)
118                 printf("x%d: %d\t",i+1,x[i]);
119             printf("\n");
120         }
121         else if (ret > 0)
122         {
123             printf("无穷多解,自由变元 %d 个\n",ret);
124             for (int i=0;i<var;i++)
125                 if (free_x[i])
126                     printf("x%d:不缺定\t",i+1);
127                 else
128                     printf("x%d: %d\t",i+1,x[i]);
129             printf("\n");
130         }
131     }
132 
133     return 0;
134 }
135 /*
136 3 3
137 1 2 4 6
138 2 6 3 9
139 1 2 3 6
140 
141 3 2
142 2 -4 -2
143 4 -5 2
144 5 -9 1
145 
146 3 5
147 1 1 1 1 1 10
148 1 1 1 0 1 8
149 1 1 0 1 1 3
150 
151 1 1 1  1 1 10
152 0 0 -1 1 0 -7
153 0 0 0 -1 0 -2
154 */
View Code

 

posted @ 2017-06-06 21:38  happy_codes  阅读(178)  评论(0编辑  收藏  举报