Java实现十字形开关问题(“飞行员兄弟“)

主要通过位运算
“飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有 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]='+';
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值