poj 1222 EXTENDED LIGHTS OUT (高斯消元 )

http://poj.org/problem?id=1222

题意:

题目大意:给一个5*6的01矩阵,0表示灯暗的,1表示灯亮着。矩阵中每个位置表示一个按钮,当按钮按动时它周围(上下左右)的灯变成相反的状态。问怎么按可以将所有的灯都变成暗的。

题解:首先我们知道每一个灯只能按一次 ,因为 按两次 等于不安

和 1830 一样 只不过是 变为了 二维,我么只要 对它门重新编号就可以了 。

依然是

E(a) = xa*A11 ^ xb*A12 ^ xc*A13 ^ S(a);

E(b) = xa*A21 ^ xb*A22 ^ xc*A23 ^ S(b);

E(c) = xa*A31 ^ xb*A32 ^ xc*A33 ^ S(c);

 解中 1 表示 按 0表示 不安,所以我门只要 统计 解中 1 的个数就可以了

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include< set>
  7 #include<map>
  8 #include<queue>
  9 #include<vector>
 10 #include< string>
 11  #define Min(a,b) a<b?a:b
 12  #define Max(a,b) a>b?a:b
 13  #define CL(a,num) memset(a,num,sizeof(a));
 14  #define maxn  40
 15  #define eps  1e-6
 16  #define inf 9999999
 17  #define mx 1<<60
 18  using  namespace std;
 19  int mat[maxn][maxn] ;
 20  int x[maxn] ;
 21  int free_x[maxn] ;
 22 
 23 
 24  int gcd( int a, int b)
 25 {
 26      int t;
 27      while(b !=  0)
 28     {
 29         t = b;
 30         b = a%b;
 31         a = t;
 32     }
 33      return a;
 34 }
 35  int lcm( int a, int b)
 36 {
 37      return (a*b)/gcd(a,b);
 38 }
 39  int  Gauss( int  var, int equ)
 40 {
 41 
 42      int i,j,k,col;
 43      int max_r;
 44      int ta,tb;
 45      int LCM;
 46      int free_x_num;
 47      int free_index;
 48      int tmp ;
 49     CL(x, 0);
 50 
 51      for(k =  0 , col =  0;k < equ && col <  var;k ++,col++)
 52     {
 53         max_r = k;
 54          for(i = k +  1; i < equ ;++i)
 55         {
 56              if(abs(mat[i][col]) > abs(mat[max_r][col]))max_r = i;
 57         }
 58 
 59 
 60 
 61          if(max_r != k)
 62         {
 63              for(i = col; i <  var+ 1;++i) //
 64              {
 65                 swap(mat[k][i],mat[max_r][i]);
 66             }
 67         }
 68          if(mat[k][col] ==  0)
 69         {
 70             k--;
 71              continue ;
 72         }
 73 
 74 
 75          for(i = k  +  1; i < equ;i++)
 76         {
 77              if(mat[i][col])
 78             {
 79 
 80                  for(j = col;j <  var +  1; j++)
 81                 {
 82 
 83                     mat[i][j] = mat[i][j]^mat[k][j] ;//注意这里 可以改为(mat[i][j]% 2 - mat[k][j]%2 + 2)%2;下面一样
 84 
 85                 }
 86             }
 87 
 88         }
 89 
 90     }
 91 
 92 
 93      for(i = k; i < equ ;i++) //
 94      {
 95          if(mat[i][col]!=  0return - 1 ;
 96     }
 97 
 98 
 99 
100      for(i =  var -  1 ; i >=  0;i--)
101     {
102          int tmp = mat[i][ var] ;
103          for(j = i ; j <  var ;j++)
104         {
105              if(j != i) tmp ^= mat[i][j]*x[j] ;
106 
107         }
108         x[i] = tmp ;
109     }
110       return   0;
111 }
112  int cal( int i, int j)
113 {
114      return i * 6 + j ;
115 }
116  void init()
117 {
118     CL(mat, 0);
119      int i,j;
120      for( i = 0 ; i <  5;i++)
121     {
122          for(j =  0; j <  6;j++)
123         {
124              int x = cal(i ,j);
125             mat[x][x] =  1;
126              if(i -  1 >= 0)
127             {
128                  int y = cal(i -  1,j);
129                 mat[x][y] =  1;
130 
131             }
132              if(j +  1 <  6)
133             {
134                  int y = cal(i,j +  1);
135                 mat[x][y] =  1;
136             }
137              if(i +  1 <  5)
138             {
139                  int y = cal(i+ 1,j);
140                 mat[x][y] =  1;
141 
142             }
143 
144              if(j -  1 >= 0)
145             {
146                  int y = cal(i,j -  1);
147                 mat[x][y] =  1;
148             }
149         }
150     }
151 
152 
153 }
154  int main()
155 {
156     int t,i,j,a;
157 
158     // freopen("data.txt","r",stdin);
159 
160    scanf( " %d ",&t);
161     int cas =  0;
162 
163     while(t--)
164    {
165          init();
166         for( i =  0 ; i <  5 ; i++)
167        {
168             for(j =  0; j <  6;j++)
169            {
170                scanf( " %d ",&a);
171                mat[i *  6 + j][ 30] = a;
172 
173            }
174        }
175 
176         Gauss( 30, 30);
177         printf( " PUZZLE #%d\n ",++cas);
178          for( i =  0; i <  30;i++)
179         {
180              if(i %  6 ==  0)printf( " %d ",x[i]);
181              else printf( "  %d ",x[i]);
182              if(i% 6 ==  5 )printf( " \n ");
183         }
184 
185 
186    }
187 
188 }

你可能感兴趣的:(extend)