题目链接: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;
}
京公网安备 11010502036488号