题意:有一个5 * 6的矩阵,每个位置表示灯,1表示灯亮,0表示灯灭。
然后如果选定位置i,j点击,则位置i,j和其上下左右的灯的状态都会反转。
现在要你求出一个5 * 6的矩阵,1表示这个灯被点击过,0表示没有。
要求这个矩阵能够使得原矩阵的灯全灭。
开始没有理解到说的那个at bt ct 是什么
其实是在A[i][j]按下去的时候他所影响到的 li位置处的状态,这个状态在一个矩阵的M*N 的N M确定之后就随着确定了,不过我没有找到其中的规律,><
然后利用模2加的性质就是相当于异或运算,就可以构造出方程式来出x(i,j)的每一个值
https://blog.csdn.net/u013508213/article/details/47263183
#include <iostream>// 用G++,还有就是不能外挂
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
//#define IO ios::sync_with_stdio(false),cin.tie(0), cout.tie(0);
//#pragma comment(linker, "/STACK:1024000000,1024000000")
void ex_gcd(int a, int b, int &d, int &x, int &y) { if (!b) { x = 1; y = 0; d = a; } else { ex_gcd(b, a%b, d, y, x); y -= x * (a / b); }; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
int lcm(int a,int b){return a/gcd(a,b)*b;}//先除后乘防溢出
int inv_exgcd(int a, int m) { int d, x, y;ex_gcd(a, m, d, x, y);return d == 1 ? (x + m) % m : -1; }
typedef long long ll;
const int maxn=1e3;
using namespace std;
int a[maxn][maxn];
int x[maxn];
int n,m;
bool free_x[maxn];//记录不确定的变元
void init()
{
memset(a,0,sizeof(a));
for(int i=0;i<5;++i)
for(int j=0;j<6;++j)///表示对这个A[i][j]确定的上下左右的每个位置的状态进行初始化没有找到其中的规律
{
int t=i*6+j;
a[t][t]=1;
if(i>0)a[(i-1)*6+j][t]=1;
if(i<4)a[(i+1)*6+j][t]=1;
if(j>0)a[i*6+j-1][t]=1;
if(j<5)a[i*6+j+1][t]=1;
}
}
int Gauss(int equ,int var)
{
int max_r,col,k;
int ta,tb;
int Lcm;
int temp;
int free_x_num=0,free_index;
for(int i=0;i<=var;++i) x[i]=0,free_x[i]=true;
//转化为阶梯例
col=0;//当前列
for( k=0,col=0;k<equ&&col<var;++k,++col)
{//枚举当前行
max_r=k;
for(int i=k+1;i<equ;++i)
if(abs(a[i][col])>abs(a[max_r][col]))max_r=i;
if(max_r!=k)
for(int i=k;i<=var;++i) swap(a[k][i],a[max_r][i]);///i=0;
if(!a[k][col])
{
k--;
continue;//处理下一列
}
for(int i=k+1;i<equ;++i)
{//化为阶梯型
if(a[i][col])
{
// Lcm=lcm(abs(a[i][col]),abs(a[k][col]));
// ta=Lcm/abs(a[i][col]),tb=Lcm/abs(a[k][col]);
// if(a[i][col]*a[k][col]<0)tb=-tb;
for(int j=col;j<=var;++j)
{
a[i][j]^=a[k][j];//((a[i][j]*ta-a[k][j]*tb));
}
}
}
}
for(int i=k;i<equ;++i)// 无解
if(a[i][col]) return -1;
if(k<var)// 无穷解
{///这这儿可以直接 return var-k;不用求出未知元
// for(int i=k-1;i>=0;--i)
// {
// free_x_num=0;//用于判断不确定性变元的数量,若超过一个仍然无法求解(无解)
// for(int j=0;j<var;++j)
// if(a[i][j]&&free_x[j])free_x_num++,free_index=j;
// if(free_x_num>1)continue;
// temp=a[i][var];
// for(int j=0;j<var;++j)
// {
// if(a[i][j]&&j!=free_x_num)temp=(temp-a[i][j]*x[j]);
// }
// x[free_index]=(temp/a[i][free_index])%7;
// free_x[free_index]=false;
// }
return var-k;
}
//唯一解
for(int i=var-1;i>=0;--i)
{
temp=a[i][var];
for(int j=i+1;j<var;++j)
if(a[i][j])temp=(temp^(a[i][j]&&x[j]));//cout<<temp<<endl;
x[i]=temp;
}
return 0;
}
int main()
{
int t;
cin>>t;
for(int ca=1;ca<=t;++ca)
{
init();
for(int i=0;i<30;++i)
scanf("%d",&a[i][30]);
int free_num=Gauss(30,30);
printf("PUZZLE #%d\n",ca);
for(int i=0;i<30;++i)
{
printf("%d",x[i]);
if((i+1)%6==0)
printf("\n");
else
printf(" ");
}
}
return 0;
}