高斯消元系列

高斯第一篇 

poj1222 EXTENDED LIGHTS OUT 

状压枚举法

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100000
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 int f[10][1<<6],a[8],b[8][8],o[10][1<<6];
 18 char s[8][8];
 19 int main()
 20 {
 21     int i,j,g,t,kk=0;
 22     cin>>t;
 23     while(t--)
 24     {
 25         for(i = 1 ; i <= 5 ; i++)
 26         {
 27             for(j = 0 ; j < 6 ; j++)
 28             {
 29                 cin>>s[i][j];
 30                 b[i][j] = s[i][j]-'0';
 31             }
 32         }
 33 
 34         for(i = 0 ; i < (1<<6) ; i++)
 35         {
 36             for(j = 0 ; j < 6 ; j++)
 37             a[j] = b[1][j];
 38             for(g = 0 ; g < 6 ; g++)
 39             if((1<<g)&i)
 40             {
 41                 if(g==0)
 42                 {
 43                     a[g] = (a[g]+1)%2;
 44                     a[g+1] = (a[g+1]+1)%2;
 45                 }
 46                 else
 47                 {
 48                     a[g] = (a[g]+1)%2;
 49                     a[g-1] = (a[g-1]+1)%2;
 50                     a[g+1] = (a[g+1]+1)%2;
 51                 }
 52             }
 53 
 54             int tt = 0;
 55             for(j = 0 ; j < 6 ; j++)
 56             tt+=(1<<j)*a[j];
 57             f[1][tt] = 1;
 58             o[1][tt] = i;
 59         }
 60         for(i = 2; i <= 5 ; i++)
 61         {
 62             for(j = 0 ; j < (1<<6) ; j++)
 63             {
 64                 if(!f[i-1][j]) continue;
 65                 for(g = 0  ;g < 6 ; g++)
 66                 a[g] = b[i][g];
 67                 for(g = 0 ; g < 6 ; g++)
 68                 {
 69                     if((1<<g)&j)
 70                     {
 71                         if(g==0)
 72                         {
 73                             a[g] = (a[g]+1)%2;
 74                             a[g+1] = (a[g+1]+1)%2;
 75                         }
 76                         else
 77                         {
 78                             a[g] = (a[g]+1)%2;
 79                             a[g-1] = (a[g-1]+1)%2;
 80                             a[g+1] = (a[g+1]+1)%2;
 81                         }
 82                     }
 83                     if(o[i-1][j]&(1<<g))
 84                     a[g]= (a[g]+1)%2;
 85                 }
 86                 int sum=0;
 87                 for(g = 0 ; g < 6 ; g++)
 88                 sum+=(1<<g)*a[g];
 89                 f[i][sum] = f[i-1][j];
 90                 o[i][sum] = j;
 91             }
 92         }
 93         int t = 0;
 94         printf("PUZZLE #%d
",++kk);
 95         for(i = 5 ; i >= 1; i--)
 96         {
 97             t = o[i][t];
 98             for(j = 0 ; j < 6 ; j++)
 99             {
100                 if(t&(1<<j))
101                 b[i][j] = 1;
102                 else
103                 b[i][j] = 0;
104             }
105         }
106         for(i = 1 ; i <= 5 ; i++)
107         {
108             for(j = 0 ; j < 5 ; j++)
109             cout<<b[i][j]<<" ";
110             cout<<b[i][5];
111             cout<<endl;
112         }
113         //puts("");
114     }
115     return 0;
116 }
View Code

高斯消元

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 100000
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 int x[42][42],ans[32];
18 int gauss()
19 {
20     int i,j,k;
21     for(k = 0 ;k < 30 ; k++)//依次将第k列变换为0
22     {
23         i = k;
24         while(i<30&&x[i][k]==0) i++;
25         if(i!=k)//找出第一个k列不为0的行 与之交换  因为是01 一般的会找出最大的
26         {
27             for(j = 0 ; j <= 30 ; j++)
28             swap(x[k][j],x[i][j]);
29         }
30         //i++;
31         for(i = 0 ;i <30 ; i++)//所有行与第k行进行运算 
32         {
33             if(i==k||x[i][k]==0)
34             {
35                 continue;
36             }
37             for(j = 0 ;j <= 30 ; j++)
38             {
39                 x[i][j]^=x[k][j];//因为01矩阵的特殊性 直接异或就可以了
40             }
41         }
42     }
43     for(i = 0 ;i < 30 ;i++)
44     {
45         if(x[i][30])
46         {
47             for(j = 0 ; j < 30&&x[i][j]==0 ; j++);
48             if(j==30) return 0;
49             else ans[j] = x[i][30];//也是因为01矩阵的特殊性 免去了解一元方程的麻烦
50         }
51     }
52     return 1;
53 }
54 int main()
55 {
56     int i,j,n,kk=0;
57     cin>>n;
58     while(n--)
59     {
60         memset(ans,0,sizeof(ans));
61         memset(x,0,sizeof(x));
62         for(i =0 ;i < 30 ;i++)
63         {
64             scanf("%d",&x[i][30]);
65         }
66         for(i =0 ; i < 30 ;i++)//构造矩阵 行为开关 列为灯  一个开关可以控制5个灯
67         {
68             x[i][i] = 1;
69            if(i>5) x[i][i-6] = 1;
70            if(i%6>0) x[i][i-1] = 1;
71            if(i%6<5) x[i][i+1] = 1;
72            if(i+6<30) x[i][i+6] = 1;
73         }
74         /*for(i = 0 ;i < 30 ;i++)
75         {
76             int tx = i/6;
77             int ty = i%6;
78             x[i][i] = 1;
79             for(j = 0 ; j < 30 ; j++)
80             {
81                 int kx = j/6;
82                 int ky = j%6;
83                 if(abs(tx-kx)+abs(ty-ky)<=1)
84                 x[i][j] = 1;
85             }
86         }*/
87         gauss();
88         printf("PUZZLE #%d
",++kk);
89         for(i = 0 ; i < 30 ;i++)
90         {
91             cout<<ans[i];
92             if((i+1)%6==0) puts("");
93             else cout<<" ";
94         }
95     }
96     return 0;
97 }
View Code

线代都忘干净了。。看了N多博客 及讲解 把上篇最简单的高斯消元入门题搞懂。下面贴几篇讲的不错的博客。

如果对线代没什么概念的话 还是先看下文库的概念及理论 文库讲解

对高斯消元的解析及例题 czyuan原创

高斯消元的模板 比较全的模板 包括无解 有解及多解  模板

然后是对此题详细的讲解 感谢这位 看了他的博客 才明白了这道题  poj1222详解

再大体说一下 这题构造出矩阵 套上模板就可以A了 对于初学,的确不知道怎么构造矩阵,什么叫构造矩阵,先从开关与灯的关系入手,每个开关可以控制5台灯,边上的另算,这样就可以构造出一个开关与灯的01矩阵 A (30*30) 题的目的就是让灯从初始状态变为全0 当然可以逆着来 从0 变为初始状态 所以把初始状态化成一个单位向量 输入为1 B[i] = 1  那就可以列出式子

AX=B X为所求。

 POJ 1681 Painter's Problem

这个题与上题类似 不同的地方在于此题可能有多解 需要找出变换次数最小的解 那就要枚举自由元 不知道自由元的话可以看一下上面文库里的概念 每个自由元有两种取值 0,1 每取一次,就会确定方程的一组解 这样从中选出一个最小的 网上大部分题解说是把自由元取为0就可以了 不过没有一篇博客给出证明。。难道这样的结论显而易见? 反正我没证出来,不过我验证了那样写交上去是对的。。还是又用了保险一点的方法,就以普通方法对自由元进行枚举,从中选取最小的。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100000
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 int a[230][230],n,free_x[230],x[230];
 18 int gauss()
 19 {
 20     int i,j,k;
 21     int m = n*n;
 22     int e= 0,g;
 23     int num = 0;
 24     for(k = 0 ;k < m&&e< m; k++,e++)
 25     {
 26         i = k;
 27         while(i<m&&a[i][e]==0) i++;
 28         if(i==m)
 29         {
 30             k--;
 31             free_x[num++] = e;
 32             continue;
 33         }
 34         if(i!=k)
 35         {
 36             for(j = 0; j<= m ;j++)
 37             swap(a[i][j],a[k][j]);
 38         }
 39         for(i = k+1 ; i < m ;i++)
 40         {
 41             if(a[i][e])
 42             {
 43                 for(j = e ;j <= m ;j++)
 44                 a[i][j]^=a[k][j];
 45             }
 46         }
 47     }
 48     for(i = k ; i < m ;i++)
 49     if(a[i][m]) return -1;
 50     if(k<m)
 51     {
 52         int cnt = 0,minz=INF;
 53         int tt = m-k;
 54         for(i =0  ;i < (1<<tt) ; i++)
 55         {
 56             cnt = 0;
 57             memset(x,0,sizeof(x));
 58             for(j = 0 ;j < tt ; j++)
 59             {
 60                 if(i&(1<<j))
 61                 {
 62                     x[free_x[j]] = 1;
 63                     cnt++;
 64                 }
 65             }
 66             for(j = k-1;  j >= 0; j--)
 67             {
 68                 for(g = j ; g < m ;g++)
 69                 {
 70                     if(a[j][g]) break;
 71                 }
 72                 x[g] = a[j][m];
 73                 for(e = g+1 ; e < m ; e++)
 74                 {
 75                     if(a[j][e])
 76                     x[g]^=x[e];
 77                 }
 78                 cnt+=x[g];
 79             }
 80             minz = min(minz,cnt);
 81         }
 82         return minz;
 83     }
 84     for(i = m-1 ; i >= 0 ;i--)
 85     {
 86         x[i] = a[i][m];
 87         for(j = i+1 ;j < m ; j++)
 88         if(a[i][j])
 89         x[i] ^= x[j];
 90 
 91     }
 92     int cnt=0;
 93     for(i =0  ;i < m ;i++)
 94     if(x[i]) cnt++;
 95     return cnt;
 96 }
 97 int main()
 98 {
 99     int t,i;
100     cin>>t;
101     while(t--)
102     {
103         cin>>n;
104         memset(a,0,sizeof(a));
105         for(i = 0 ; i < n*n; i++)
106         {
107             char c;
108             cin>>c;
109             if(c=='y')
110             a[i][n*n] = 0;
111             else
112             a[i][n*n] = 1;
113         }
114         for(i = 0; i < n*n ; i++)
115         {
116             a[i][i] = 1;
117             if(i%n>0) a[i-1][i] = 1;
118             if(i%n<n-1) a[i+1][i] = 1;
119             if(i>=n) a[i-n][i] = 1;
120             if(i+n<n*n) a[i+n][i] = 1;
121         }
122         int cnt = gauss();
123         if(cnt==-1)
124         {
125             puts("inf");
126             continue;
127         }
128         cout<<cnt<<endl;
129     }
130     return 0;
131 }
View Code

POJ 1830 开关问题

求解的个数 因为只能取01  所以无穷解变成了 2^k k为自由元的个数 

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 100000
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 int a[32][32],b[32],c[32],n;
18 int gauss()
19 {
20     int i,j,k,g=1;
21     for(k = 1 ; k <= n && g<=n;k++,g++)
22     {
23         i = k;
24         while(i<=n&&a[i][g]==0) i++;
25         if(i>n)
26         {
27             k--;
28             continue;
29         }
30         if(i!=k)
31         {
32             for(j = 1; j <= n+1 ;j++)
33             swap(a[i][j],a[k][j]);
34         }
35         for(i = k+1 ; i <= n ;i++)
36         {
37             if(a[i][g])
38             {
39                 for(j = g ; j <= n+1;  j++)
40                 a[i][j]^=a[k][j];
41             }
42         }
43     }
44     for(i = k ; i <= n ;i++)
45     {
46         if(a[i][n+1]!=0) return 0;
47     }
48     return pow(2.0,n+1-k);
49 }
50 int main()
51 {
52     int t,i;
53     cin>>t;
54     while(t--)
55     {
56         memset(a,0,sizeof(a));
57         cin>>n;
58         for(i = 1; i <= n ;i++)
59         cin>>b[i];
60         for(i = 1; i <= n ;i++)
61         {
62             cin>>c[i];
63             b[i] = (c[i]+b[i])%2;
64             a[i][i] = 1;
65             a[i][n+1] = b[i];
66         }
67         int u,v;
68         while(cin>>u>>v)
69         {
70             if(!u&&!v) break;
71             a[v][u] = 1;
72         }
73         int k = gauss();
74         if(!k) {puts("Oh,it's impossible~!!");continue;}
75         cout<<k<<endl;
76     }
77     return 0;
78 }
View Code

POJ 1753 Flip Game

与1681一样 枚举自由元的状态

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100000
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 int a[230][230],n,free_x[230],x[230];
 18 int gauss()
 19 {
 20     int i,j,k;
 21     int m = n*n;
 22     int e= 0,g;
 23     int num = 0;
 24     for(k = 0 ;k < m&&e< m; k++,e++)
 25     {
 26         i = k;
 27         while(i<m&&a[i][e]==0) i++;
 28         if(i==m)
 29         {
 30             k--;
 31             free_x[num++] = e;
 32             continue;
 33         }
 34         if(i!=k)
 35         {
 36             for(j = 0; j<= m ;j++)
 37             swap(a[i][j],a[k][j]);
 38         }
 39         for(i = k+1 ; i < m ;i++)
 40         {
 41             if(a[i][e])
 42             {
 43                 for(j = e ;j <= m ;j++)
 44                 a[i][j]^=a[k][j];
 45             }
 46         }
 47     }
 48     for(i = k ; i < m ;i++)
 49     if(a[i][m]) return -1;
 50     if(k<m)
 51     {
 52         int cnt = 0,minz=INF;
 53         int tt = m-k;
 54         for(i =0  ;i < (1<<tt) ; i++)
 55         {
 56             cnt = 0;
 57             memset(x,0,sizeof(x));
 58             for(j = 0 ;j < tt ; j++)
 59             {
 60                 if(i&(1<<j))
 61                 {
 62                     x[free_x[j]] = 1;
 63                     cnt++;
 64                 }
 65             }
 66             for(j = k-1;  j >= 0; j--)
 67             {
 68                 for(g = j ; g < m ;g++)
 69                 {
 70                     if(a[j][g]) break;
 71                 }
 72                 x[g] = a[j][m];
 73                 for(e = g+1 ; e < m ; e++)
 74                 {
 75                     if(a[j][e])
 76                     x[g]^=x[e];
 77                 }
 78                 cnt+=x[g];
 79             }
 80             minz = min(minz,cnt);
 81         }
 82         return minz;
 83     }
 84     for(i = m-1 ; i >= 0 ;i--)
 85     {
 86         x[i] = a[i][m];
 87         for(j = i+1 ;j < m ; j++)
 88         if(a[i][j])
 89         x[i] ^= x[j];
 90 
 91     }
 92     int cnt=0;
 93     for(i =0  ;i < m ;i++)
 94     if(x[i]) cnt++;
 95     return cnt;
 96 }
 97 int main()
 98 {
 99     int t,i;
100     cin>>t;
101     while(t--)
102     {
103         cin>>n;
104         memset(a,0,sizeof(a));
105         for(i = 0 ; i < n*n; i++)
106         {
107             char c;
108             cin>>c;
109             if(c=='y')
110             a[i][n*n] = 0;
111             else
112             a[i][n*n] = 1;
113         }
114         for(i = 0; i < n*n ; i++)
115         {
116             a[i][i] = 1;
117             if(i%n>0) a[i-1][i] = 1;
118             if(i%n<n-1) a[i+1][i] = 1;
119             if(i>=n) a[i-n][i] = 1;
120             if(i+n<n*n) a[i+n][i] = 1;
121         }
122         int cnt = gauss();
123         if(cnt==-1)
124         {
125             puts("inf");
126             continue;
127         }
128         cout<<cnt<<endl;
129     }
130     return 0;
131 }
View Code
 

POJ 3185 The Water Bowls  

20个方程 与上面的类似 枚举自由元 选取最小的

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100000
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 int a[22][22],x[22],free_x[22];
 18 int gauss()
 19 {
 20     int i,j,g=0,k;
 21     int num=0;
 22     for(k =0  ;k < 20 && g<20; k++,g++)
 23     {
 24         i = k;
 25         while(i<20&&a[i][g]==0) i++;
 26         if(i==20)
 27         {
 28             k--;
 29             free_x[num++] = g;
 30             continue;
 31         }
 32         if(i!=k)
 33         {
 34             for(j =0 ; j <= 20 ; j++)
 35             swap(a[i][j],a[k][j]);
 36         }
 37         for(i = k+1 ; i < 20; i++)
 38         {
 39             if(a[i][g])
 40             {
 41                 for(j = g; j <= 20 ; j++)
 42                 a[i][j]^=a[k][j];
 43             }
 44         }
 45     }
 46     if(k<20)
 47     {
 48         int cnt=0,minz=INF,tt = 20-k;
 49         for(i =0 ; i< (1<<tt) ; i++)
 50         {
 51             memset(x,0,sizeof(x));
 52             cnt = 0;
 53             for(j = 0  ;j < tt ; j++)
 54             {
 55                 if(i&(1<<j))
 56                 {
 57                     cnt++;
 58                     x[free_x[j]] = 1;
 59                 }
 60             }
 61             for(j = k-1 ; j >= 0; j--)
 62             {
 63                 for(g = j ;  g < 20 ; g++)
 64                 if(a[j][g]) break;
 65                 x[g] = a[j][20];
 66                 for(int e = g+1; e < 20 ; e++)
 67                 if(a[j][e])
 68                 x[g]^=x[e];
 69                 cnt+=x[g];
 70             }
 71             minz = min(minz,cnt);
 72         }
 73         return minz;
 74     }
 75     int cnt = 0;
 76     for(i = 19 ; i >= 0; i--)
 77     {
 78         x[i] = a[i][20];
 79         for(j = i+1 ; j < 20 ; j++)
 80         x[i]^=x[j];
 81         cnt+=x[i];
 82     }
 83     return cnt;
 84 }
 85 int main()
 86 {
 87     int i,b;
 88     while(cin>>b)
 89     {
 90         memset(a,0,sizeof(a));
 91         a[0][20] = b;
 92         for(i = 1; i < 20 ;i++)
 93         {
 94             cin>>b;
 95             a[i][20] = b;
 96         }
 97         for(i = 0 ;i < 20 ; i++)
 98         {
 99             if(i>0) a[i-1][i] = 1;
100             a[i][i] = 1;
101             if(i<19) a[i+1][i] = 1;
102         }
103         int k = gauss();
104         cout<<k<<endl;
105     }
106     return 0;
107 }
View Code

POJ 2947 Widget Factory  

上面几题都是 01 矩阵的一些求解 ,从这题开始就是一些Modp的一些求解 其实也与之类似 参考着最上面的模板理解一下计算方法 这一类的题目都很类似,不是很难

这题有几个需要注意的地方 要看清题目中说的时间要在3-9天内  在截止时间减开始时间的时候需要不断对7取余 计算时也需要不断对7取余 因为需要整数解 在最后求x[i]的时候需要不断+mod来使得最后的解为一个整数 各种细心啊。。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100000
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 int a[310][310],x[310],n,m;
 18 int judge(char *s)
 19 {
 20     if(strcmp(s,"MON")==0) return 1;
 21     if(strcmp(s,"TUE")==0) return 2;
 22     if(strcmp(s,"WED")==0) return 3;
 23     if(strcmp(s,"THU")==0) return 4;
 24     if(strcmp(s,"FRI")==0) return 5;
 25     if(strcmp(s,"SAT")==0) return 6;
 26     return 7;
 27 }
 28 int gcd(int a,int b)
 29 {
 30     int t;
 31     while(b!=0)
 32     {
 33         t = b;
 34         b = a%b;
 35         a = t;
 36     }
 37     return a;
 38 }
 39 int gauss()
 40 {
 41     int i,j,k,g=0;
 42     for(k = 1 ; k <= m && g <= n;k++,g++)
 43     {
 44         i = k;
 45         int maxz = a[i][g];
 46         for(j = k+1 ; j <= m ;j++)
 47         if(a[j][g]>maxz)
 48         {
 49             maxz = a[j][g];
 50             i = j;
 51         }
 52         if(a[i][g]==0)
 53         {
 54             k--;
 55             continue;
 56         }
 57         if(i!=k)
 58         {
 59             for(j = 1 ; j<= n+1 ;j++)
 60             swap(a[i][j],a[k][j]);
 61         }
 62         for(i = k+1; i <= m ; i++)
 63         {
 64             if(a[i][g])
 65             {
 66                 int gc = gcd(a[i][g],a[k][g]);
 67                 int lm = a[i][g]/gc*a[k][g];
 68                 int u1 = lm/a[i][g];
 69                 int u2 = lm/a[k][g];
 70                 if(a[i][g]*a[k][g]<0) u2 = -u2;
 71                 for(j = g ; j <= n+1 ; j++)
 72                 {
 73                     a[i][j] = ((u1*a[i][j]-u2*a[k][j])%7+7)%7;
 74                 }
 75             }
 76         }
 77     }
 78     for(i = k ; i<= m ; i++)
 79     if(a[i][n+1]) return -1;
 80     if(k<n+1) return 0;
 81     for(i = n ;i >= 1 ;i--)
 82     {
 83         int s = a[i][n+1];
 84         for(j = i+1 ; j <= n ;j++)
 85         {
 86             s-=a[i][j]*x[j];
 87             s=(s%7+7)%7;
 88         }
 89         while(s%a[i][i]!=0) s+=7;
 90         x[i] = ((s/a[i][i])%7+7)%7;
 91     }
 92     return 1;
 93 }
 94 int main()
 95 {
 96     int i,j,k;
 97     char s1[20],s2[20];
 98     while(scanf("%d%d",&n,&m)&&n&&m)
 99     {
100         memset(a,0,sizeof(a));
101         memset(x,0,sizeof(x));
102         for(i = 1 ;i <= m ;i++)
103         {
104             scanf("%d %s %s",&k,s1,s2);
105             int t1 = judge(s1),t2 = judge(s2),t;
106             t = (t2-t1+1+7)%7;
107             a[i][n+1] = t;
108             for(j = 1; j <= k ;j++)
109             {
110                 int u;
111                 cin>>u;
112                 a[i][u]++;
113                 a[i][u]%=7;
114             }
115         }
116         int k = gauss();
117         if(k==-1)
118             puts("Inconsistent data.");
119         else if(k==0)
120             puts("Multiple solutions.");
121         else
122         {
123             for(i = 1 ; i < n ;i++)
124             {
125                 if(x[i]<3) x[i]+=7;
126                 printf("%d ",x[i]);
127             }
128             if(x[i]<3) x[i]+=7;
129             printf("%d
",x[i]);
130         }
131     }
132     return 0;
133 }
View Code

POJ 2065 SETI  

题意看了好久。。题目中给出了一个式子 0=<i<=n-1  aik^i 和 = f(k) k从1取到n n为字符串长度 f(k)用字符串来表示 a-z代表1-26 *代表0 

n个方程很好想到 。。写完发现样例过不去,看了下discuss说是什么范德萌行列式,又说挺难得,我以为想错了,看了下题解,发现跟我写的一样,仔细一看不是 

a-'a'而是a-'a'+1  细心啊。。。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100000
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 int pp[75][75],a[75][75],x[75];
 18 int md;
 19 char s[75];
 20 void init(int n)
 21 {
 22     int i,j;
 23     for(i = 1 ; i <= n ; i++)
 24     {
 25         pp[i][0] = 1;
 26         for(j = 1 ; j < n ; j++)
 27         pp[i][j] = (pp[i][j-1]*i)%md;
 28     }
 29 }
 30 int gcd(int a,int b)
 31 {
 32     int t;
 33     while(b)
 34     {
 35         t = b;
 36         b = a%b;
 37         a = t;
 38     }
 39     return a;
 40 }
 41 void gauss(int n)
 42 {
 43     int k,i,j,g=0;
 44     for(k = 0;  k < n && g < n ; k++,g++)
 45     {
 46         i = k;
 47         int maxz = a[i][g];
 48         for(j = k+1 ; j < n ;j++)
 49         if(maxz<a[j][g])
 50         {
 51             maxz = a[j][g];
 52             i = j;
 53         }
 54         if(a[i][g]==0)
 55         {
 56             k--;
 57             continue;
 58         }
 59         if(i!=k)
 60         {
 61             for(j = 0 ;j <= n ;j++)
 62             swap(a[i][j],a[k][j]);
 63         }
 64         for(i = k+1 ; i < n ;i++)
 65         {
 66             if(a[i][g])
 67             {
 68                 int gc = gcd(a[i][g],a[k][g]);
 69                 int lm = a[i][g]/gc*a[k][g];
 70                 int t1 = lm/a[i][g];
 71                 int t2 = lm/a[k][g];
 72                 if(a[i][g]*a[k][g]<0) t2=-t2;
 73                 for(j = g ; j <= n ;j++)
 74                 a[i][j] = ((a[i][j]*t1-t2*a[k][j])%md+md)%md;
 75             }
 76         }
 77     }
 78     for(i = n-1  ;i >= 0 ;i--)
 79     {
 80         int s = a[i][n];
 81         for(j = i+1 ; j < n ;j++)
 82         {
 83             s-=a[i][j]*x[j];
 84             s = (s%md+md)%md;
 85         }
 86         while(s%a[i][i]!=0) s+=md;
 87         x[i] = s/a[i][i];
 88     }
 89     //cout<<k<<endl;
 90     for(i =0 ; i< n-1 ; i++)
 91     printf("%d ",x[i]);
 92     printf("%d
",x[i]);
 93 }
 94 int main()
 95 {
 96     int i,j,t,k;
 97     cin>>t;
 98     while(t--)
 99     {
100         cin>>md;
101         cin>>s;
102         k = strlen(s);init(k);
103         memset(a,0,sizeof(a));
104         memset(x,0,sizeof(x));
105         for(i = 0 ; i < k ;i++)
106         {
107             if(s[i]!='*')
108             a[i][k] = s[i]-'a'+1;
109             else
110             a[i][k] = 0;
111         }
112         for(i = 1; i <= k; i++)
113         {
114             for(j = 0 ; j < k ;j++)
115             a[i-1][j] = pp[i][j];
116         }
117         gauss(k);
118     }
119     return 0;
120 }
View Code

poj1166 The Clocks  这题其实不想贴的,感觉这题用高斯来解有些问题,4不为素数,计算中模的话解就变了,自己写的高斯死活过不去,参考着discuss中的一个高斯代码改了改,发现只能按他那一种写法可过 ,像计算中不取余,初等行变换的时候找第一个不为0的 ,找最大的进行交换就会错,用最小公倍数算也会错,各种不行啊。。

这题大部分是枚举过的 ,以前USACO上早就刷过,贴个自己改的不成样子的高斯吧

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100000
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 int a[20][20],x[10],free_x[10],o[10];
 18 int gcd(int a,int b)
 19 {
 20     int t;
 21     while(b)
 22     {
 23         t = b;
 24         b = a%b;
 25         a = t;
 26     }
 27     return a;
 28 }
 29 void gauss()
 30 {
 31     int i,j,g=0,k;
 32     int num = 0;
 33     for(k = 0 ;k < 9 ; k++)
 34     {
 35         i = k;
 36         for(j = k ; j< 9 ; j++)
 37         {
 38             if(a[j][k]!=0)
 39             {
 40                 i = j;
 41                 break;
 42             }
 43         }
 44         if(i!=k)
 45         {
 46             for(j =0  ;j <= 9 ;j++)
 47             swap(a[i][j],a[k][j]);
 48         }
 49         for(i = k+1 ; i < 9 ; i++)
 50         {
 51             if(a[i][k])
 52             {
 53                 /*int gc= gcd(a[i][g],a[k][g]);
 54                 int lm = a[i][g]/gc*a[k][g];
 55                 int t1 = lm/a[i][g];
 56                 int t2 = lm/a[k][g];
 57                // if(a[i][g]*a[k][g]<0) t2 = -t2;*/
 58                int tt = a[i][k];
 59                 for(j = k ; j <= 9 ;j++)
 60                 {
 61                     //a[i][j] = a[i][j]*t1-a[k][j]*t2;//)((%4+4)%4;;
 62                     a[i][j]*=a[k][k];
 63                     a[i][j]-=a[k][j]*tt;
 64                 }
 65             }
 66         }
 67     }
 68     for(i = 8 ; i >= 0; i--)
 69     {
 70         if(a[i][i])
 71         {
 72             int s = a[i][9];
 73             for(j = i+1 ; j < 9 ; j++)
 74             {
 75                 s-=a[i][j]*x[j];
 76 
 77             }
 78             s = (s%4+4)%4;
 79             for(j = 0 ; j <= 3  ;j++)
 80             if(((j*a[i][i])%4+4)%4==s) x[i] = j;
 81             /*while(s%a[i][i]!=0) {s+=4;}
 82             x[i] = s/a[i][i];//cout<<",";*/
 83         }
 84     }
 85     for(i =0 ; i< 9 ; i++)
 86     x[i] = (x[i]%4+4)%4;
 87     int tk = 0;
 88     for(i = 0 ;i < 9 ; i++)
 89     {
 90         while(x[i])
 91         {
 92             if(tk) printf(" ");
 93             tk++;
 94             printf("%d",i+1);
 95             x[i]--;
 96         }
 97     }
 98     puts("");
 99 }
100 int main()
101 {
102     int i,b,j;
103 
104     while(cin>>b)
105     {
106         memset(x,0,sizeof(x));
107         memset(a,0,sizeof(a));
108         for(i = 0 ; i < 9 ; i++)
109          {
110             switch(i)
111             {
112                 case 0: a[0][i] = a[1][i] = a[3][i] = a[4][i] = 1;break;
113                 case 1: a[0][i] = a[1][i] = a[2][i] = 1;break;
114                 case 2: a[1][i] = a[2][i] = a[4][i] = a[5][i] = 1;break;
115                 case 3: a[0][i] = a[3][i] = a[6][i] = 1;break;
116                 case 4: a[1][i] = a[3][i] = a[4][i] = a[5][i] = a[7][i] = 1;break;
117                 case 5: a[2][i] = a[5][i] = a[8][i] = 1;break;
118                 case 6: a[3][i] = a[4][i] = a[6][i] = a[7][i] = 1;break;
119                 case 7: a[6][i] = a[7][i] = a[8][i] = 1;break;
120                 case 8: a[4][i] = a[5][i] = a[7][i] = a[8][i] = 1;break;
121             }
122          }
123         a[0][9] = (4-b)%4;
124         for(i = 1; i < 9 ; i++)
125         {
126             cin>>b;
127             a[i][9] = (4-b)%4;
128         }
129         gauss();
130     }
131     return 0;
132 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3601241.html