题目链接: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; }