高斯消元 模板

照着czyuan的那个模板,手敲了一遍,存一下。

貌似今天一整天就看了一下高斯消元的知识,然后看了模板,又手敲了一遍。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cmath>
  6 #include <algorithm>
  7 #define LL __int64
  8 const int maxn = 100+10;
  9 using namespace std;
 10 int equ, var, fn;
 11 int a[maxn][maxn], x[maxn];
 12 bool free_x[maxn];
 13 
 14 int gcd(int a, int b)
 15 {
 16     return b==0?a:gcd(b, a%b);
 17 }
 18 int lcm(int a, int b)
 19 {
 20     return a*b/gcd(a, b);
 21 }
 22 int Gauss()
 23 {
 24     int i, j, k, max_r, col;
 25     int ta, tb, LCM, tmp, fx_num;
 26     int free_index;
 27     col = 0;
 28 
 29     for(k = 0; k<equ && col<var; k++, col++)
 30     {
 31         max_r = k;
 32         for(i = k+1; i < equ; i++)
 33             if(abs(a[i][col])>abs(a[max_r][col]))
 34             max_r = i;
 35 
 36         if(max_r != k)
 37             for(j = k; j < var+1; j++)
 38             swap(a[k][j], a[max_r][j]);
 39 
 40         if(a[k][col]==0)
 41         {
 42             k--;
 43             continue;
 44         }
 45         for(i = k+1; i < equ; i++)
 46         {
 47             if(a[i][col] != 0)
 48             {
 49                 LCM = lcm(abs(a[i][col]), abs(a[k][col]));
 50                 ta = LCM/abs(a[i][col]);
 51                 tb= LCM/abs(a[k][col]);
 52                 if(a[i][col]*a[k][col] < 0) tb = -tb;
 53 
 54                 for(j = col; j < var+1; j++)
 55                 a[i][j] = a[i][j]*ta - a[k][j]*tb;
 56             }
 57         }
 58     }
 59     for(i = k; i < equ; i++)
 60     if(a[i][col] != 0)
 61     return -1;
 62 
 63     if(k < var)
 64     {
 65         for(i = k-1; i >= 0; i--)
 66         {
 67             fx_num = 0;
 68             for(j = 0; j < var; j++)
 69                 if(a[i][j]!=0 && free_x[j])
 70                 {
 71                     fx_num ++;
 72                     free_index = j;
 73                 }
 74             if(fx_num > 1) continue;
 75 
 76             tmp = a[i][var];
 77             for(j = 0; j < var; j++)
 78                 if(a[i][j] != 0 && j!=free_index)
 79                 tmp -= a[i][j]*x[j];
 80 
 81             x[free_index] = tmp/a[i][free_index];
 82             free_x[free_index] = 0;
 83         }
 84         return var-k;
 85     }
 86     for(i = var-1; i >= 0; i--)
 87     {
 88         tmp = a[i][var];
 89         for(j = i+1; j < var; j++)
 90         if(a[i][j] != 0)
 91         tmp -= a[i][j]*x[j];
 92 
 93         if(tmp%a[i][i] != 0) return -2;
 94         x[i] = tmp/a[i][i];
 95     }
 96     return 0;
 97 }
 98 int main()
 99 {
100     int i, j;
101     while(cin>>equ>>var)
102     {
103         memset(a, 0, sizeof(a));
104         memset(x, 0, sizeof(x));
105         memset(free_x, 1, sizeof(free_x));
106         for(i = 0; i < equ; i++)
107         {
108             for(j = 0; j < var+1; j++)
109             cin>>a[i][j];
110         }
111 
112         fn = Gauss();
113         if(fn == -1) cout<<"无解"<<endl;
114         else if(fn == -2)
115         cout<<"有浮点数解, 无整数解"<<endl;
116         else if(fn > 0)
117         {
118             printf("无穷多解! 自由变元个数为%d\n", fn);
119             for(i = 0; i < var; i++)
120             {
121                 if(free_x[i]) printf("x%d行 是不确定的\n", i + 1);
122                 else printf("x%d: %d\n", i + 1, x[i]);
123             }
124         }
125         else
126         {
127             for(i = 0; i < var; i++)
128             printf("x%d: %d\n", i + 1, x[i]);
129         }
130         cout<<endl;
131     }
132     return 0;
133 }

 

 

浮点型的模板

eps那里和整型不一样

 1 #define eps 1e-8
 2 const int maxn = 100+10;
 3 using namespace std;
 4 int equ, var;
 5 double a[maxn][maxn], x[maxn];
 6 
 7 int Gauss()
 8 {
 9     int i, j, k, max_r, col;
10     double tmp;
11     col = 0;
12 
13     for(k = 0; k<equ && col<var; k++, col++)
14     {
15         max_r = k;
16         for(i = k+1; i < equ; i++)
17             if(fabs(a[i][col])-fabs(a[max_r][col]) > eps)
18             max_r = i;
19 
20         if(max_r != k)
21             for(j = k; j < var+1; j++)
22             swap(a[k][j], a[max_r][j]);
23 
24         if(fabs(a[k][col]) < eps)
25         {
26             k--;
27             continue;
28         }
29         for(i = k+1; i < equ; i++)
30         {
31             if(fabs(a[i][col]) > eps)
32             {
33                 double t = a[i][col]/a[k][col];  //这里和整型的不同。
34                 a[i][col] = 0.0;
35 
36                 for(j = col; j < var+1; j++)
37                 a[i][j] -= a[k][j]*t;
38             }
39         }
40     }
41     for(i = var-1; i >= 0; i--)
42     {
43         if(fabs(a[i][i]) < eps) continue;
44         tmp = a[i][var];
45         for(j = i+1; j < var; j++)
46         if(a[i][j] != 0)
47         tmp -= a[i][j]*x[j];
48 
49         //if(tmp%a[i][i] != 0) return -2;
50         x[i] = tmp/a[i][i];
51     }
52     return 0;
53 }

 

 

 

模mo的情况下的模板:

根据上面的模板改的,但是正确性有待验证

 

 1 int gcd(int a, int b)
 2 {
 3     return b==0?a:gcd(b, a%b);
 4 }
 5 int lcm(int a, int b)
 6 {
 7     return a*b/gcd(a, b);
 8 }
 9 int Gauss()
10 {
11     int x_mo;
12     x_mo = 2;  //初始化为2了。
13     int i, j, k, max_r, col;
14     int ta, tb, LCM, tmp, fx_num;
15     int free_index;
16     col = 0;
17 
18     for(k = 0; k<equ && col<var; k++, col++)
19     {
20         max_r = k;
21         for(i = k+1; i < equ; i++)
22             if(abs(a[i][col])>abs(a[max_r][col]))
23                 max_r = i;
24 
25         if(max_r != k)
26             for(j = k; j < var+1; j++)
27                 swap(a[k][j], a[max_r][j]);
28 
29         if(a[k][col]==0)
30         {
31             k--;
32             continue;
33         }
34         for(i = k+1; i < equ; i++)
35         {
36             if(a[i][col] != 0)
37             {
38                 LCM = lcm(abs(a[i][col]), abs(a[k][col]));
39                 ta = LCM/abs(a[i][col]);
40                 tb= LCM/abs(a[k][col]);
41                 if(a[i][col]*a[k][col] < 0) tb = -tb;
42 
43                 for(j = col; j < var+1; j++)
44                     a[i][j] = ((a[i][j]*ta - a[k][j]*tb)%x_mo+x_mo)%x_mo;
45             }
46         }
47     }
48     for(i = k; i < equ; i++)
49         if(a[i][col] != 0)
50             return -1;
51 
52     if(k < var)  //正确性有待验证
53     {
54         for(i = k-1; i >= 0; i--)
55         {
56             fx_num = 0;
57             for(j = 0; j < var; j++)
58                 if(a[i][j]!=0 && free_x[j])
59                 {
60                     fx_num ++;
61                     free_index = j;
62                 }
63             if(fx_num > 1) continue;
64 
65             tmp = a[i][var];
66             for(j = 0; j < var; j++)
67                 if(a[i][j] != 0 && j!=free_index)
68                     tmp = ((tmp-a[i][j]*x[j])%x_mo+x_mo)%x_mo;
69             if(a[i][free_index]==0)  //这里我也改了,因为也会出现0的情况。
70                 x[free_index] = 0;
71             else
72             {
73                 while(tmp%a[i][free_index]!=0)  //正确性有待验证
74                     tmp += x_mo;  //正确性有待验证
75                 x[free_index] = (tmp/a[i][free_index])%x_mo; //正确性有待验证
76             }
77             free_x[free_index] = 0;
78         }
79         return var-k;
80     }
81 
82     for(i = var-1; i >= 0; i--)
83     {
84         tmp = a[i][var];
85         for(j = i+1; j < var; j++)
86             if(a[i][j] != 0)
87                 tmp = ((tmp-a[i][j]*x[j])%x_mo+x_mo)%x_mo;
88 
89         if(a[i][i]==0) //这我改了,因为做题的时候发现有a[][]等于0的情况,会出现除0
90             x[i] = 0;
91         else
92         {
93             if(tmp%a[i][i] != 0) return -2;  //这个的位置应该放这。
94             while(tmp%a[i][i]!=0) tmp += x_mo;
95             x[i] = (tmp/a[i][i])%x_mo;
96         }
97     }
98     return 0;
99 }

 

 

 

 

 

这个和上面的模板不一样,也有判断多解和无解的情况。

 1 int Gauss ()
 2 {
 3     int x_mo;
 4     x_mo = 7;  //初始为7了。
 5     int i, j, mr, row, col;
 6     int ta, tb, l, tmp;
 7     row = col = 0;
 8     while ( row < equ && col < var )
 9     {
10         mr = row;
11         for ( i = row + 1; i < equ; i++ )
12             if ( abs(a[i][col]) > abs(a[mr][col]) ) mr = i;
13 
14 
15         if ( mr != row )
16             for ( j = col; j <= var; j++ )
17                 swap ( a[row][j], a[mr][j] );
18         if ( a[row][col] == 0 )
19         {
20             col++;
21             continue;
22         }
23 
24 
25         for ( i = row + 1; i < equ; i++ )
26         {
27             if ( a[i][col] != 0 )
28             {
29                 l = lcm(abs(a[i][col]), abs(a[row][col]));
30                 ta = l / abs(a[i][col]), tb = l / abs(a[row][col]);
31                 if ( a[i][col] * a[row][col] < 0 ) tb = -tb;
32                 for ( j = col; j <= var; j++ )
33                     a[i][j] = ((a[i][j]*ta-a[row][j]*tb)%x_mo+x_mo) % x_mo;
34             }
35         }
36         row++;
37         col++;
38     }
39 
40     for ( i = row; i < equ; i++ )
41         if ( a[i][var] != 0 ) return -1;
42 
43 
44     if ( row < var )
45         return var - row;
46 
47 
48     for ( i = var - 1; i >= 0; i-- )
49     {
50         tmp = a[i][var];
51         for ( j = i + 1; j < var; j++ )
52             tmp = ((tmp-a[i][j]*x[j])%x_mo+x_mo)%x_mo;
53         while ( tmp % a[i][i] != 0 ) tmp += x_mo;
54         x[i] = ( tmp / a[i][i] ) % x_mo;
55     }
56     return 0;
57 }

 

这个是判断模2 情况下的模板,注意只是模2,不会出现除0的情况,但是没有找自由变元的处理

 1 int  Gauss()
 2 {
 3     int i,j,k;
 4     int max_r;
 5     int col;
 6     int temp;
 7 
 8     int free_x_num;
 9     int free_index;
10 
11     col=0;
12     for(k=0;k<equ&&col<var;k++,col++)
13     {
14         max_r=k;
15         for(i=k+1;i<equ;i++)
16         {
17             if(abs(a[i][col])>abs(a[max_r][col]))max_r=i;
18         }
19         if(max_r!=k)
20         {
21             for(j=col;j<var+1;j++)swap(a[k][j],a[max_r][j]);
22         }
23         if(a[k][col]==0)
24         {
25             k--;
26             continue;
27         }
28         for(i=k+1;i<equ;i++)
29         {
30             if(a[i][col]!=0)
31             {
32                 for(j=col;j<var+1;j++)
33                   a[i][j]^=a[k][j];
34             }
35         }
36     }
37     for(i=k;i<equ;i++)
38     {
39         if(a[i][col]!=0)return -1;//无解
40     }
41 
42     if(k < var)
43     return var-k;
44 
45     for(i=var-1;i>=0;i--)
46     {
47         x[i]=a[i][var];
48         for(j=i+1;j<var;j++)
49           x[i]^=(a[i][j]&&x[j]);
50     }
51     return 0;
52 }

 

posted @ 2014-08-15 21:35  水门  阅读(270)  评论(0编辑  收藏  举报