题目大意:有30盏灯。关闭一盏,周围的四盏也会关掉。问怎样按开关可以让所有的灯关掉。
解题报告:30个开关,每个开关最多影响5盏灯,可以列30个方程式,用高斯消元法解此方程。
注意化简矩阵时用亦或就好了,AC代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[30][31];
int x[30];
void Gauss(int equ,int var)
{
int k=0,col=0;
for(; k<equ && col<var; k++,col++)
{
int max_r=k;
for(int i=k; i<equ; i++)
if(a[i][col])
{
max_r=i;
break;
}
if(max_r!=k)
for(int j=k; j<=var; j++)
swap(a[max_r][j],a[k][j]);
if(a[k][col]==0)
{
k--;
continue;
}
for(int i=k+1; i<equ; i++) if(a[i][col])
for(int j=col; j<=var; j++)
a[i][j]^=a[k][j];
}
}
int main()
{
int T;
scanf("%d",&T);
for(int cas=1;cas<=T;cas++)
{
memset(x,0,sizeof(x));
memset(a,0,sizeof(a));
for(int i=0; i<30; i++)
{
a[i][i]=1;
if(i>5)
a[i][i-6]=1;
if(i<24)
a[i][i+6]=1;
if(i%6!=5)
a[i][i+1]=1;
if(i%6!=0)
a[i][i-1]=1;
}
for(int i=0; i<30; i++)
scanf("%d",&a[i][30]);
Gauss(30,30);
for(int i=29; i>=0; i--)
{
int temp=a[i][30];
for(int j=i+1; j<30; j++) if(a[i][j])
temp^=a[i][j]&x[j];
x[i]=temp;
}
printf("PUZZLE #%d\n",cas);
for(int i=0; i<30; i++)
{
printf("%d",x[i]);
printf(i%6==5?"\n":" ");
}
}
}