第一行灯的亮暗由第一行和第二行来决定,因此:假如第一行确定了,那么第二行就确定了,依次类推,第三行确定,第四行确定,第五行确定。
所以说只需要遍历第一行的情况即可,然后下面一行灯是否按动由上面一行灯的状态来决定。
首先由while来循环选择的矩阵,此时要输入要写在这个while里面下面的for外面,同时当前矩阵的最短步数也要写在while里面下面的for外面 ,然后由for来循环选择当前矩阵的第一行的32种情况,接下来要对当前矩阵进行操作,因此还需要创建一个傀儡矩阵来进行操作,当前矩阵作为模板,每次重新选择矩阵的第一行时,就对傀儡矩阵进行刷新。
第一行的灯状态的通过01来表示,0表示灯的状态不变,1表示灯的状态改变。
序列表示的是二进制数,for循环十进制数,然后通过>>来间接将其转换为二进制数,然后通过&来判断当前位置的值是1还是0。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 6;
char bk[N][N], st[N][N];
int n;
int dx[] = {1,0,-1,0,0}, dy[] = {0,1,0,-1,0};
//turn:改变包括这个灯在内的5个灯的状态
void turn(int x, int y)
{
for(int i = 0; i < 5 ; i ++ )
{
int a = x + dx[i],b = y + dy[i];
if(a < 0 || b < 0 || b > 5 || a > 5 ) continue;
st[a][b]^=1;
}
}
int main()
{
cin >> n;
while(n--)
{
int res = 10;
for(int i = 0; i < 5 ; i ++ ) cin >> st[i];
for(int op = 0; op < 32; op ++ )
{
memcpy(bk,st,sizeof st);
int step = 0;
for(int i = 0;i < 5; i ++ )
{
if(op >> i & 1)
{
step ++ ;
turn(0,i);
}
}
for(int i = 0; i < 4; i ++ )
for(int j = 0; j < 5 ; j ++ )
{
if(st[i][j] == '0')
{
step ++ ;
turn(i+1,j);
}
}
bool it = false;
for(int i = 0; i < 5; i ++ )
{
if(st[4][i]=='0')
{
it = true;
break;
}
}
if(!it)res = min(res,step);
memcpy(st,bk,sizeof bk);
}
if(res > 6) cout << -1 << endl;
else cout << res << endl;
}
return 0;
}
turn:改变包括这个灯在内的5个灯的状态
for(int op = 0; op < 32; op ++ )
{
memcpy(bk,st,sizeof st);
int step = 0;
for(int i = 0;i < 5; i ++ )
{
if(op >> i & 1)
{
step ++ ;
turn(0,i);
}
}
第一行的32种情况,
step表示步数,第二个for依次检查第一行每个灯(从后到前)的状态
for(int i = 0; i < 4; i ++ )
for(int j = 0; j < 5 ; j ++ )
{
if(st[i][j] == '0')
{
step ++ ;
turn(i+1,j);
}
}
对剩下四行进行操作,每一行的操作由上一行来决定
bool it = false;
for(int i = 0; i < 5; i ++ )
{
if(st[4][i]=='0')
{
it = true;
break;
}
}
if(!it)res = min(res,step);
memcpy(st,bk,sizeof bk);
}
if(res > 6) cout << -1 << endl;
else cout << res << endl;
整个操作完毕之后,要判断是否能将其全部化为1,同时step<6,然后按情况对result进行操作,