农夫过河问题(java版)

问题描述:
一个农夫带着一只狼、一只羊、一只白菜,身处河南岸,要把全部东西带到北岸。问题是只有一条小船,船只能容纳他和一件东西,且狼吃羊,羊吃白菜。问:农夫怎样才能将所有东西安全带到河对岸。

代码实现:

package com.my.courseDesign;

public class CourseDesign {
    /*
    * 1.   首先分为A岸,和B岸,A岸用0来表示,B岸用1来表示,在船上用1来表示,不再船上用0表示
    * 2.   分别创建两个大小为4数组分别用来表示过河前和过河后的状态coast[4],cross[4],
    *      再创建一个二维数组表示存储过河方式boat[][]
    * 3.   经过分析符合岸上安全的情况为{0,0,0,0}、{1,1,1,1}、{1,0,1,0}、{1,1,1,0}、
    *      {1,1,0,1}、{1,0,1,1}、{0,1,0,0}、{0,0,1,0}、{0,0,0,1}、{0,1,0,1}十种情况,
    *      过河有{1,0,0,0}{1,1,0,0}{1,0,1,0}{1,0,0,1}四种情况
    *      经过分析发现如果假设:1(船)+1(岸)=0,0(船)+0(岸)=0,0(船)+1(岸)=1,1(船)+0(岸)=1成立则过完河
    *      之后的情况正好是四者过完河后在岸上的状态,思考后发现可以用求余的方式来实现
    * 4.   创建一个方法返回过完河后两岸状态
    * 5.   创建一个方法来判断过完河后状态是否为安全状态,如果不是则接着遍历,是的话则打印过河状态
    * 6.   创建一个方法对该次过河进行打印
    * 7.   创建一个方法将过完河后的状态赋值给过河前状态
    * 8.   通过循环遍历对过河进行实现
    *
    *
    *
    * */
    static int[] coast={0,0,0,0};   //表示过河前状态
    static int[][] boat={{1,1,0,0},{1,0,1,0},{1,0,0,1},{1,0,0,0}};  //所有过河方式
    static int[] cross=new int[4];   //表示过完河后的状态
    public static void main(String[] args){
        while (coast[0]+coast[1]+coast[2]+coast[3]!=4){  //只要四者没有全部到B岸就一直过河
            for (int i=0;i<4;i++){      //对四种过河方式进行对比
                nextCoast(i,coast,boat);    //调用nextCoast()方法返回过完河后两岸状态
                if (isSafe(cross)){   //调用isSafe()方法判断过完河后是否都处于安全状态
                    print();    //如果都安全则调用print()方法对该次过河进行打印
                    exchangCoast();   //调用exchangCoast()方法将过完河后的状态赋值给过河前状态
                    System.out.println();   //换行
                }
            }
        }
        System.out.println("过河成功!");   //所有人过完之后输出成功
    }
    public static void nextCoast(int i,int[] coast,int[][] boat){  //编写nextCoast()方法返回过完河后两岸状态
        cross[0]=(coast[0]+boat[i][0])%2;     //通过取余来实现做出的设定
        cross[1]=(coast[1]+boat[i][1])%2;
        cross[2]=(coast[2]+boat[i][2])%2;
        cross[3]=(coast[3]+boat[i][3])%2;
    }
    public static boolean isSafe(int[] cross){    //编写isSafe()方法判断过完河后是否都处于安全状态
        if(       //对10种安全的情况依次做对比
            (cross[0]==1 && cross[1]==1 && cross[2]==1 && cross[3]==1) ||
            (cross[0]==0 && cross[1]==0 && cross[2]==0 && cross[3]==0) ||
            (cross[0]==1 && cross[1]==0 && cross[2]==1 && cross[3]==0) ||
            (cross[0]==1 && cross[1]==1 && cross[2]==1 && cross[3]==0) ||
            (cross[0]==1 && cross[1]==1 && cross[2]==0 && cross[3]==1) ||
            (cross[0]==1 && cross[1]==0 && cross[2]==1 && cross[3]==1) ||
            (cross[0]==0 && cross[1]==1 && cross[2]==0 && cross[3]==0) ||
            (cross[0]==0 && cross[1]==0 && cross[2]==1 && cross[3]==0) ||
            (cross[0]==0 && cross[1]==0 && cross[2]==0 && cross[3]==1) ||
            (cross[0]==0 && cross[1]==1 && cross[2]==0 && cross[3]==1)
        ){
            return true;
        }else{
            return false;
        }
    }
    public static void print(){    //编写print()方法对该次过河进行打印
        if (cross[0]==1){
            System.out.print("从A岸到B岸:");
        }else{
            System.out.print("从B岸到A岸:");
        }
        if(cross[0]!=coast[0]){
            System.out.print("人");
        }
        if(cross[1]!=coast[1]){
            System.out.print("带狼");
        }
        if(cross[2]!=coast[2]){
            System.out.print("带羊");
        }
        if(cross[3]!=coast[3]){
            System.out.print("带白菜");
        }
        System.out.print("过河");
    }
    public static void exchangCoast(){   //编写exchangCoast()方法将过完河后的状态赋值给过河前状态
        for (int i=0;i<4;i++){
            coast[i]=cross[i];
        }
    }
}

运行结果展示:

从A岸到B岸:人带羊过河
从B岸到A岸:人过河
从A岸到B岸:人带狼过河
从B岸到A岸:人带羊过河
从A岸到B岸:人带白菜过河
从B岸到A岸:人过河
从A岸到B岸:人带羊过河
过河成功!
原文地址:https://www.cnblogs.com/shenzhenhuaya/p/15226181250_shenzhenhua0211.html