题目链接:http://poj.org/problem?id=1222
就是亮灯问题
56的灯,列30个方程,异或方程组一套板子,完事
*
代码:**

#include <iostream>  
#include <stdio.h>  
#include <string.h>   
#include <stack>  
#include <queue>   
#include <map>  
#include <set>  
#include <vector>  
#include <math.h>  
#include <bitset>  
#include <algorithm>  
#include <climits>

#define MAXN  50
#define N 50
#define INF 0X3f3f3f3f
using namespace std;

struct Node
{
    int x, y;
    Node(int x=0, int y=0):x(x),y(y){}
}dir[4];

int a[N][N];//增广矩阵
int x[N];//解集
int freeX[N];//自由变元
int Gauss(int equ,int var){//返回自由变元个数
    /*初始化*/
    for(int i=0;i<=var;i++){
        x[i]=0;
        freeX[i]=0;
    }

    /*转换为阶梯阵*/
    int col=0;//当前处理的列
    int num=0;//自由变元的序号
    int row;//当前处理的行
    for(row=0;row<equ&&col<var;row++,col++){//枚举当前处理的行
        int maxRow=row;//当前列绝对值最大的行
        for(int i=row+1;i<equ;i++){//寻找当前列绝对值最大的行
            if(abs(a[i][col])>abs(a[maxRow][col]))
                maxRow=i;
        }
        if(maxRow!=row){//与第row行交换
            for(int j=row;j<var+1;j++)
                swap(a[row][j],a[maxRow][j]);
        }
        if(a[row][col]==0){//col列第row行以下全是0,处理当前行的下一列
            freeX[num++]=col;//记录自由变元
            row--;
            continue;
        }

        for(int i=row+1;i<equ;i++){
            if(a[i][col]!=0){
                for(int j=col;j<var+1;j++){//对于下面出现该列中有1的行,需要把1消掉
                    a[i][j]^=a[row][j];
                }
            }
        }
    }

    /*求解*/
    //无解:化简的增广阵中存在(0,0,...,a)这样的行,且a!=0
    for(int i=row;i<equ;i++)
        if(a[i][col]!=0)
            return -1;

    //无穷解: 在var*(var+1)的增广阵中出现(0,0,...,0)这样的行
    int temp=var-row;//自由变元有var-row个
    if(row<var)//返回自由变元数
        return temp;

    //唯一解: 在var*(var+1)的增广阵中形成严格的上三角阵
    for(int i=var-1;i>=0;i--){//计算解集
        x[i]=a[i][var];
        for(int j=i+1;j<var;j++)
            x[i]^=(a[i][j]&&x[j]);
    }
    return 0;
}
int enumFreeX(int freeNum,int var){//枚举自由元,统计有解情况下1最少的个数
    int sta=(1<<(freeNum));//自由元的状态总数
    int res=INF;
    for(int i=0;i<sta;++i){//枚举状态
        int cnt=0;
        for(int j=0;j<freeNum;j++){//枚举自由元
            if(i&(1<<j)){
                cnt++;
                x[freeX[j]]=1;
            }else
                x[freeX[j]]=0;
        }
        for(int k=var-freeNum-1;k>=0;k--){//没有自由元的最下面一行
            int index=0;
            for(index=k;k<var;index++){//在当前行找到第一个非0自由元
                if(a[k][index])
                    break;
            }
            x[index]=a[k][var];
            for(int j=index+1;j<var;++j){//向后依次计算出结果
                if(a[k][j])
                    x[index]^=x[j];
            }
            cnt+=x[index];//若结果为1,则进行统计
        }
        res=min(res,cnt);
    }
    return res;
}

//

int mp[MAXN][MAXN];

int main()
{
    int T, cas = 0;
    cin>>T;
    while(T--)
    {
        int equ = 30,var = 30;
        memset(a, 0, sizeof(a));
        for(int i = 0;  i<5; i++) {
            for(int j = 0; j < 6; j++){
                scanf("%d",&mp[i][j]);
            }
        }
        //
        for(int i = 0; i < 30; i++){
            a[i][i] = 1;
        }
        //
        for(int i = 0;  i<5; i++) {
            for(int j = 0; j < 6; j++){
                dir[0]  = {i-1, j};
                dir[1] = {i+1, j};
                dir[2] = {i, j-1};
                dir[3] = {i, j+1};

                //
                int vv = i*6+j;
                for(int q = 0; q < 4; q++){
                    if(dir[q].x < 0 || dir[q].y < 0 || dir[q].x >= 5 || dir[q].y >= 6) continue;
                    int ee = dir[q].x*6+dir[q].y;
                    a[ee][vv] ^= 1;    
                }
            }
        }

        for(int i=0;i<equ;i++)//最终状态
            a[i][var] = mp[i/6][i%6];


//        for(int i = 0; i < 30; i++){
//            for(int j = 0; j <= 30; j++){
//                printf("%d ",a[i][j]);
//            }
//            printf("\n");
//        }

        printf("PUZZLE #%d\n",++cas);
        int freeNum=Gauss(equ,var);//获取自由元

        int row = 0;
        for(int i = 0; i < 30; i++){
            printf("%d ",x[i]);
            row=(row+1)%6;
            if(row==0)
                printf("\n");

        }
//        for(int i = 0;  i< equ; i++){
//            printf("%d ",x[i]);
//        }

    }
    return 0;    
}