题意:
$5*6$网格里有一些灯告诉你一开始开关状态,按一盏灯会改变它及其上下左右的状态,问最后全熄灭需要按那些灯,保证有解
经典问题
一盏灯最多会被按一次,并且有很明显的异或性质
一个灯作为一个方程一个变量
两盏灯相互影响系数设为1
常数项代表最后需不需要这盏灯改变状态
解这个异或方程组就行了
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <bitset> using namespace std; const int N=35; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n=30,_; bitset<N> a[N]; void ini(){ for(int i=1;i<=n;i++) a[i].reset(); } char s[N]; void Gauss(){ int now=1; for(int i=1;i<=n;i++){ int j=now; while(j<=n&&!a[j][i]) j++; if(now!=j) swap(a[now],a[j]); for(int k=1;k<=n;k++) if(k!=now&&a[k][i]) a[k]^=a[now]; now++; } } int main(){ freopen("in","r",stdin); int T=read(),cas=0; while(T--){ for(int i=1;i<=5;i++) for(int j=1;j<=6;j++){ int id=(i-1)*6+j; a[id][id]=1; if(i!=1) a[id][id-6]=1; if(i!=5) a[id][id+6]=1; if(j!=1) a[id][id-1]=1; if(j!=6) a[id][id+1]=1; a[id][n+1]=read(); } Gauss(); printf("PUZZLE #%d ",++cas); for(int i=1;i<=5;i++) for(int j=1;j<=6;j++) _=(i-1)*6+j,printf("%d%c",a[_][n+1]==1?1:0,j==6?' ':' '); } }