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 }
原文地址:https://www.cnblogs.com/acSzz/p/2661684.html