Java解农夫过河问题

博客围绕农夫带狼、羊、白菜过河问题展开。将过程分为岸上和过河两部分,用数组表示状态和过河方法。通过穷举下一个可能的过河状态,判断是否为安全状态,若安全则打印并保存状态,循环结束后输出过河成功。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述
一个农夫带着一只狼、一只羊、一只白菜,身处河南岸,要把全部东西带到北岸。问题是只有一条小船,船只能容纳他和一件东西,且狼吃羊,羊吃白菜。问:农夫怎样才能将所有东西安全带到河对岸。
运行截图
在这里插入图片描述
算法描述
一、我们将整个过程分为在岸上,和过河两个部分。其中在岸上部分我们用一维数组currentState{X1,X2,X3,X4}表示。X1代表人,X2代表狼,X3代表羊,X4代表白菜。X1、X2、X3、X4只能取0和1。0表示在南岸,1表示在北岸。所以我们得目标是将初始状态{0,0,0,0}变为{1,1,1,1}即currentState[0]+currentState[1]+currentState[2]+currentState[3]==4,即将人、狼、羊、白菜从南岸全部运向北岸。而过河部分我们用二维数组method{X1,X2,X3,X4}表示。X1代表人,X2代表狼,X3代表羊,X4代表白菜。X1、X2、X3、X4只能取0和1。0表示不在船上,1表示在船上。

二、通过题意,我们发现currentState的取值只能为{1,1,1,1},{1,1,1,0},{1,1,0,1},{1,0,1,1},{1,0,1,0},{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,1,0,0},{0,1,0,1}这十种状态才能为安全的状态。method的取值只能为{1,1,0,0},{1,0,1,0},{1,0,0,1},{1,0,0,0}这四种方法才能过河。

三、我们用testState数组来容纳下一个可能的过河后的状态,通过
ChooseState(currentState,method[i])方法穷举下一个可能的过河后的状态,这个方法通过二进制加法来表示,即1+1=0,1+0=1,0+1=1,0+0=0。这样正好可以表示渡河后的所有状态。

四、接着我们用IsSafeState(testState)方法方法来判断testState是否为(1)中所说的安全的在岸上的状态。若不为则继续遍历方法,若为,则用DisplayState()方法打印过河的状态,并用AcceptState()方法保存testState状态为currentState状态。

五、当循环结束后,则表示遍历完成,这时输出过河成功!。

代码

public class FarmerToBridge {
	static int[] testState = new int[4];//试探下一个状态
	static int[] currentState = {0,0,0,0};//记录目前的状态
	static int[][] method = {{1,1,0,0},{1,0,0,0},{1,0,1,0},{1,0,0,1}};//过河方法
	public static void main(String[] args) {
		while(currentState[0]+currentState[1]+currentState[2]+currentState[3]!=4) {//都到达北岸为止
			for(int i=0;i<4;i++) {//遍历下一个状态
				ChooseState(currentState,method[i]);//试探这个状态
				if (IsSafeState(testState)) {//判断是否为安全状态
					DisplayState();//展示这个状态
					AcceptState();//接收这个状态
					System.out.println("");
				}
			}
		}
		System.out.println("过河成功!");
	}
	
	public static void ChooseState(int currentState[],int method[]) {
		testState[0] = (currentState[0]+method[0])%2;
		testState[1] = (currentState[1]+method[1])%2;
		testState[2] = (currentState[2]+method[2])%2;
		testState[3] = (currentState[3]+method[3])%2;
	}
	
	public static Boolean IsSafeState(int testState[]) {
		if (State(testState)) {
			return true;
		}else {
			return false;
		}
	}
	
	public static Boolean State(int testState[]) {
		if (  (testState[0]==1 && testState[1]==1 && testState[2]==1 && testState[3]==1)
			||(testState[0]==1 && testState[1]==1 && testState[2]==1 && testState[3]==0)
			||(testState[0]==1 && testState[1]==1 && testState[2]==0 && testState[3]==1)
			||(testState[0]==1 && testState[1]==0 && testState[2]==1 && testState[3]==1)
			||(testState[0]==1 && testState[1]==0 && testState[2]==1 && testState[3]==0)
			||(testState[0]==0 && testState[1]==0 && testState[2]==0 && testState[3]==0)
			||(testState[0]==0 && testState[1]==0 && testState[2]==0 && testState[3]==1)
			||(testState[0]==0 && testState[1]==0 && testState[2]==1 && testState[3]==0)
			||(testState[0]==0 && testState[1]==1 && testState[2]==0 && testState[3]==0)
			||(testState[0]==0 && testState[1]==1 && testState[2]==0 && testState[3]==1)
			) {
			return true;
		}else {
			return false;
		}
	}
	
	public static void DisplayState() {
		if(testState[0]==1) {
			System.out.print("南-->北:");
		}else {
			System.out.print("北-->南:");
		}
		if (testState[0] != currentState[0]) {
			System.out.print("人");
		}
		if (testState[1] != currentState[1]) {
			System.out.print("带狼");
		}
		if (testState[2] != currentState[2]) {
			System.out.print("带羊");
		}
		if (testState[3] != currentState[3]) {
			System.out.print("带白菜");
		}
		System.out.print("过河");

	}
	
	public static void AcceptState() {
		for(int j=0;j<4;j++) {
			currentState[j] = testState[j];
		}
	}
}

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值