穿越隧道
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 510, M = 10;
char g[M][M],backup[M][M];
int dx[5] = {-1,0,1,0,0};
int dy[5] = {0,1,0,-1,0};
int n;
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 && a < 5 && b >= 0 && b < 5){
g[a][b] ^= 1;
/*
因为字符0和字符1,字符0为48,字符1为49(ASCII)。
所以通过异或最后一位达到字符1和0的转化。
*/
}
}
}
int main(){
scanf("%d",&n);
while(n--){
for(int i = 0; i < 5; i++) scanf("%s",g[i]);
int res = 10;
for(int op = 0; op < 32; op++){//枚举第一行所有的按法 2^5 = 32次,因题目要找最优解。
memcpy(backup,g,sizeof(g));
int step = 0;
/*处理第一行:
1.此处1表示按,0表示不按。
为下面行做准备
*/
for(int i = 0; i < 5; i++){//第一行中的每一个元素
if(op >> i & 1){//op为第一行按灯开关的32种方式。某一种方式的二进制的哪几位为1,则进行turn操作
step++;
turn(0,i);
}
}
for(int i = 0; i < 4; i++){
for(int j = 0; j < 5; j++){
if(g[i][j] == '0'){
step++;
turn(i+1,j);//第i行固定了,只能通过i+1行来改变第i行的状态。
}
}
}
/*遍历最后一行的每一个元素,看这个方案下,是否能使最后一行灯全亮*/
bool succ = true;
for(int i = 0; i < 5; i++){
if(g[4][i] == '0'){
succ = false;
break;
}
}
if(succ) res = min(res,step);
memcpy(g,backup, sizeof(g));//将原始数组赋给g.
}
if(res > 6) puts("-1");
else printf("%d\n",res);
}
return 0;
}