[poj1222]EXTENDED LIGHTS OUT(高斯消元)

题意:每个灯开启会使自身和周围的灯反转,要使全图的灯灭掉,判断灯开的位置。

解题关键:二进制高斯消元模板题。

复杂度:$O({n^3})$

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<algorithm>
 7 using namespace std;
 8 const int N=35;
 9 int a[N][N],ans[N];
10 int dx[5]={0,1,0,-1,0};
11 int dy[5]={0,0,1,0,-1};
12 int idx(int x,int y){return (x-1)*6+y;}
13 void gauss(int nn){
14     int i,j,k,l;
15     for(i=1,j=1;i<=nn&&j<=nn;j++){
16         for(k=i;k<=nn;k++)if(a[k][j])break;
17         if(a[k][j]){
18             for(l=1;l<=nn+1;l++) swap(a[i][l],a[k][l]);
19             for(l=1;l<=nn;l++){
20                 if(l!=i&&a[l][j])
21                     for(k=1;k<=nn+1;k++) 
22                         a[l][k]^=a[i][k];
23             }
24             i++;
25         }
26     }
27     for(j=1;j<i;j++) ans[j]=a[j][nn+1];
28 }
29 
30 int main(){
31     int T,n=5,m=6,nn=n*m;
32     scanf("%d",&T);
33     for(int ca=1;ca<=T;ca++){
34         memset(a,0,sizeof a);
35         for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&a[idx(i,j)][nn+1]);
36         for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)for(int k=0;k<=4;k++){
37             int x=i+dx[k],y=j+dy[k];
38             if(x>n||y>m||x<1||y<1) continue;
39             a[idx(i,j)][idx(x,y)]=1;
40         }
41         gauss(nn);
42         printf("PUZZLE #%d\n",ca);
43         for(int i=1;i<=30;i++)printf("%d%c",ans[i],i%6==0?'\n':' ');
44     }
45     return 0;
46 }

 

posted @ 2017-10-15 20:57  Elpsywk  阅读(176)  评论(0编辑  收藏  举报