主要通过位运算
“飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有 16 个把手的冰箱。
已知每个把手可以处于以下两种状态之一:打开或关闭。
只有当所有把手都打开时,冰箱才会打开。
把手可以表示为一个 4×4 的矩阵,您可以改变任何一个位置 [i,j] 上把手的状态。
但是,这也会使得第 i 行和第 j 列上的所有把手的状态也随着改变。
请你求出打开冰箱所需的切换把手的次数最小值是多少
import java.util.*;
import java.lang.*;
public class Main{
static char[][] st = new char[5][5];
static char[][] back = new char[5][5];
public static void main(String[] args){
Scanner in = new Scanner(System.in);
for(int i=0;i<4;i++){
st[i] = in.next().toCharArray();
back[i] = st[i]; //进行备份
}
int step = 999;
String strX = "",strY = ""; //存储路径
for(int op=0;op< (1<<16) ;op++){ //共进行2的16次操作
int res = 0;
String strX1 = "",strY1="";
for(int i=0;i<16;i++){ //根据二进制进行翻转
if((op>>i & 1)==1){
int x = i/4;
int y = i%4;
strX1+=x;
strY1+=y;
turnAll(x,y); // 进行翻转
res++;
}
}
boolean flag = true;
for(int i=0;i<4;i++){ //进行检验
for(int j=0;j<4;j++){
if(st[i][j]=='+'){
flag = false;
break;
}
}
}
if(flag==true){
if(step>res){
step=res;
}
strX = strX1;
strY = strY1;
}
res=0;
strX1="";
strY1="";
for(int i=0;i<4;i++){
st[i]=back[i].clone(); //每次操作完进行恢复
}
}
System.out.println(step);
for(int i=0;i<strX.length();i++){
int a = strX.charAt(i)-47;
int b = strY.charAt(i)-47;
System.out.println(a+" "+b);
}
}
public static void turnAll(int i,int j){
for(int m=0;m<4;m++){
turnOne(i,m);
}
for(int m=0;m<4;m++){
turnOne(m,j);
}
turnOne(i,j);
}
public static void turnOne(int i,int j){
if(st[i][j]=='+'){
st[i][j]='-';
}else{
st[i][j]='+';
}
}
}