思路 画图 尝试解决该问题
从第一行开始
枚举第一行按下灯或者不按的所有可能性
当第一行的状态已经确定下来以后
第一行可能有亮的 有暗的 因为第一行已经按完了
所以此时能改变第一行的暗灯的状态的只剩下按第二行的灯
只要第一行的灯是暗的我们就要按下他下面的第二行对应位置的灯
于是第二行的按法也确定
此时我们要通过第三行将第二行的暗灯变亮
直到按完倒数第二行 如果全亮了则有解 否则无解
、、
敲定一下细节
首先第一行按或不按 用01010的方式来表示
如果全按就是 11111 该二进制数字是31
所以0-31 表示第一行的灯按或不按的所有情况 当第一层按完
第二层的按法以及剩下的层数按法也唯一确定
开一个step来记录步数 从而让其输出六步之内的解*/
代码
#include
#include
#include
#include
using namespace std;
int n;
const int N=6;
char g[N][N],backup[N][N];
void turn (int x,int y){
int dx[5]={0,0,1,0,-1};
int dy[5]={0,1,0,-1,0};//开五个 上下左右中所有地方都要发生状态改变
for(int i=0;i<=4;i++){
int a=x+dx[i],b=y+dy[i];
if(a<0||a>5||b<0||b>5){
continue;
}
g[a][b]^=1;
}
}
int main(){
cin>>n;
while(n--)
{
for(int i=0;i<5;i++)
{
cin>>g[i];
}
int res=10;
for(int op=0;op<32;op++)
{ int step=0;
memcpy(backup,g,sizeof g);//备份数组
for(int i=0;i<5;i++)
{//从零开始 右移0位时看的是右边第一位
if(op>>i&1)
{
step++;
turn(0,i);
}
}
//枚举完第一行的所有操作后确定剩下的四行的按法
for(int i=0;i<4;i++){
for(int j=0;j<5;j++){
if(g[i][j]=='0'){
turn(i+1,j);
step++;
}
}
}
//操作完前四行
bool dark =false;
for(int i=0;i<5;i++){
if(g[4][i]=='0'){
dark=true;
break;
}
}
if(!dark){
res=min(step,res);
}
memcpy(g,backup,sizeof g);//搜完一种情况 恢复题目的原样
}
if(res>6){
res=-1;
}
cout<
return 0;
}