思路:
按照顺序,若第一行的状态固定,例如“0 1 1 0”,则第二行必须按下第2,3列,而1,4列不能按下,以此类推,只要第一行状态固定,则直至最后一行状态全部固定,所以可以通过讨论第一行的所有状态,从中寻找正确答案。
第一行一共六列,故状态有2^6=64种,枚举64种情况
代码:
#include<iostream>
#include<bitset>
#include<algorithm>
using namespace std;
int main(){
int x;
cin>>x;
bitset<6> source[5],lights[5],res[5],line;
for(int a=1;a<=x;++a)
{
for(int i=0;i<5;++i)
for(int j=0;j<6;++j)
{
int y;
cin>>y;
source[i].set(j,y);
}
for(int n=0;n<64;n++) //第一行的64种情况
{
line=n; //以二进制把第一行状态储存在line中
for(int i=0;i<5;i++)lights[i]=source[i];
for(int i=0;i<5;++i)
{
res[i]=line; //0,1在line中表示灯为暗与亮,在res中表示不按与按
for(int j=0;j<6;++j)
{
if(line.test(j)) //检测是否为1,即是否需要按下
{
if(j>0)lights[i].flip(j-1);
lights[i].flip(j);
if(j<5)lights[i].flip(j+1);
}
}
if(i<4)lights[i+1]^=line; //修改下一行灯的状态(^=应该是按位异或操 作,我是现查的资料)
line=lights[i]; // i行灯的亮暗即代表下一行应该如何按
}
if(lights[4].none()) //若最后一行为0,输出
{
cout<<"PUZZLE #"<<a<<endl;
for(int i=0;i<5;i++)
{
for(int j=0;j<6;j++)
{
cout<<res[i][j]<<" ";
}
cout<<endl;
}
break;
}
}
}
return 0;
}
^=太巧妙了