Java编程能力强化——狼羊过河问题

题目:有3只狼和3只羊要过河,只有一条船,一次最多只能坐两只动物并且每次必须有动物开船,如果某一边的狼的个数大于羊的个数,羊将被吃掉,编程给出解。

关于编程思路,参考:Java编程能力强化(2)——搜索解决方案类问题的通用解法

参考答案:

package ch1;

public class LangAndYang {

 public static void main(String[] args) {
  int state[] = {3,3};
  // 第1、2个元素表示左岸的狼和羊的数量
  new LangAndYang().next(state,null);
 }
 
 public void next(int state[],StringBuffer str){
  int[] newState;
  if(str==null){ //表示第一步
   // 一只狼一只羊
   newState = move(state,"-1-1");
   next(newState,new StringBuffer("-1-1"));
   // 两只狼过河
   newState = move(state,"-2-0");
   next(newState,new StringBuffer("-2-0"));
   return;
  }
  
  if(state[0]==0 && state[1]==0){ // 全部转移到右岸了
   printResult(str);
   return;
  }
  
  if(str!=null && hasExist(str)){ // 看是否为死循环
   return;
  }
  
  // 考虑向右转移
  if(str.charAt(0)=='+'){
   // 两只狼
   if(state[0]>=2 && !str.substring(0,4).equals("+2+0")){
    newState = move(state,"-2-0");
    if(check(newState)){
     next(newState,new StringBuffer(str).insert(0,"-2-0"));
    }
   }
   // 一只狼
   if(state[0]>=1 && !str.substring(0,4).equals("+1+0")){
    newState = move(state,"-1-0");
    if(check(newState)){
     next(newState,new StringBuffer(str).insert(0,"-1-0"));
    }
   }
   // 一只羊
   if(state[1]>=1 && !str.substring(0,4).equals("+0+1")){
    newState = move(state,"-0-1");
    if(check(newState)){
     next(newState,new StringBuffer(str).insert(0,"-0-1"));
    }
   }
   // 一只狼一只羊
   if(state[0]>=1 && state[1]>=1 && !str.substring(0,4).equals("+1+1")){
    newState = move(state,"-1-1");
    if(check(newState)){
     next(newState,new StringBuffer(str).insert(0,"-1-1"));
    }
   }
   // 两只羊
   if(state[1]>=2 && !str.substring(0,4).equals("+0+2")){
    newState = move(state,"-0-2");
    if(check(newState)){
     next(newState,new StringBuffer(str).insert(0,"-0-2"));
    }
   }
  }else{  // 考虑向左转移
   // 两只狼
   if(state[0]<2 && !str.substring(0,4).equals("-2-0")){
    newState = move(state,"+2+0");
    if(check(newState)){
     next(newState,new StringBuffer(str).insert(0,"+2+0"));
    }
   }
   // 一只狼
   if(state[0]<3 && !str.substring(0,4).equals("-1-0")){
    newState = move(state,"+1+0");
    if(check(newState)){
     next(newState,new StringBuffer(str).insert(0,"+1+0"));
    }
   }
   // 一只羊
   if(state[1]<3 && !str.substring(0,4).equals("-0-1")){
    newState = move(state,"+0+1");
    if(check(newState)){
     next(newState,new StringBuffer(str).insert(0,"+0+1"));
    }
   }
   // 一只狼一只羊
   if(state[0]<3 && state[1]<3 && !str.substring(0,4).equals("-1-1")){
    newState = move(state,"+1+1");
    if(check(newState)){
     next(newState,new StringBuffer(str).insert(0,"+1+1"));
    }
   }
   // 两只羊
   if(state[1]<2 && !str.substring(0,4).equals("-0-2")){
    newState = move(state,"+0+2");
    if(check(newState)){
     next(newState,new StringBuffer(str).insert(0,"+0+2"));
    }
   }
  }
 }
 
 /*
  * 第一个参数表示状态,第二个参数表示走法,向右用-,向左用+
  * 返回值表示新的状态
  */
 public int[] move(int state[],String info){
  int lang = 0;
  try{
   lang = Integer.parseInt(info.substring(0,2));
  }catch(Exception e){
   lang = Integer.parseInt(info.substring(1,2));
  }
  int yang = 0;
  try{
   yang= Integer.parseInt(info.substring(2));
  }catch(Exception e){
   yang = Integer.parseInt(info.substring(3));
  }
  int[] result = new int[state.length];
  result[0] = state[0]+lang;
  result[1] = state[1]+yang;
  return result;
 }
 
 /*
  * 验证状态是否合适,狼的个数不能大于羊
  */
 public boolean check(int state[]){
  if(state[0]>state[1] && state[1]>0){ //左边有羊,并且狼比羊多
   return false;
  }else if(state[0]<state[1] && state[1]<3){ // 右边有羊,并且狼比羊多
   return false;
  }else
   return true;
 }
 
 /*
  * 防止死循环,例如 先过去一只狼一只羊,然后回来一只羊,然后再过去一只狼,然后回来两只狼,就回到初始状态了
  */
 public boolean hasExist(StringBuffer str){
  int langSum=0;
  int yangSum=0;
  for(int i=0;i<str.length()/4;i++){
   if(str.charAt(i*4)=='-'){
    langSum += str.charAt(i*4+1)-'0';
    yangSum += str.charAt(i*4+3)-'0';
   }else{
    langSum -= str.charAt(i*4+1)-'0';
    yangSum -= str.charAt(i*4+3)-'0';
   }
   if(langSum==0 && yangSum==0 && i%2==1)
    return true;
  }
  return false;
 }
 
 public void printResult(StringBuffer str){
  System.out.println("-----方案------");
  for(int i=str.length()/4-1;i>=0;i--){
   if(str.charAt(i*4)=='-'){
    System.out.println("运过去"+str.charAt(i*4+1)+"只狼,"+str.charAt(i*4+3)+"只羊");
   }else{
    System.out.println("---------------运回来"+str.charAt(i*4+1)+"只狼,"+str.charAt(i*4+3)+"只羊");
   }
  }
  System.out.println();
 }
}

希望大家真正把代码理解了,而不是把代码保存下来。

人羊狼菜过河问题是一个经典的逻辑推理问题,可以使用Java代码进行分析和解决。以下是一个简单的Java代码示例,通过深度优先搜索(DFS)算法来解决该问题。 ```java import java.util.*; public class RiverCrossingProblem { // 定义人羊狼菜过河问题的初始状态 private static final int LEFT = 0; private static final int RIGHT = 1; private static final int[] INIT_STATE = {LEFT, LEFT, LEFT, LEFT}; // 定义人羊狼菜过河问题的目标状态 private static final int[] GOAL_STATE = {RIGHT, RIGHT, RIGHT, RIGHT}; // 定义人、羊、狼、菜的编号 private static final int PERSON = 0; private static final int SHEEP = 1; private static final int WOLF = 2; private static final int VEGETABLE = 3; // 定义人羊狼菜过河问题的状态 private static class State { int[] items; int boat; State parent; public State(int[] items, int boat, State parent) { this.items = items; this.boat = boat; this.parent = parent; } public boolean isGoal() { return Arrays.equals(items, GOAL_STATE); } public List<State> getNextStates() { List<State> nextStates = new ArrayList<>(); for (int i = 0; i < items.length; i++) { if (items[i] != boat) continue; int[] nextItems = items.clone(); nextItems[i] = 1 - nextItems[i]; if (isValidState(nextItems)) { nextStates.add(new State(nextItems, 1 - boat, this)); } for (int j = i + 1; j < items.length; j++) { if (items[j] != boat) continue; int[] nextItems2 = nextItems.clone(); nextItems2[j] = 1 - nextItems2[j]; if (isValidState(nextItems2)) { nextStates.add(new State(nextItems2, 1 - boat, this)); } } } return nextStates; } private boolean isValidState(int[] items) { if (items[SHEEP] == items[WOLF] && items[PERSON] != items[SHEEP]) { return false; } if (items[VEGETABLE] == items[SHEEP] && items[PERSON] != items[VEGETABLE]) { return false; } return true; } } // 使用深度优先搜索算法来解决人羊狼菜过河问题 public static void solve() { Stack<State> stack = new Stack<>(); Set<String> visited = new HashSet<>(); State initState = new State(INIT_STATE, LEFT, null); stack.push(initState); visited.add(Arrays.toString(initState.items)); while (!stack.isEmpty()) { State currentState = stack.pop(); if (currentState.isGoal()) { printPath(currentState); return; } for (State nextState : currentState.getNextStates()) { if (!visited.contains(Arrays.toString(nextState.items))) { stack.push(nextState); visited.add(Arrays.toString(nextState.items)); } } } System.out.println("No solution found!"); } // 打印求解路径 private static void printPath(State state) { List<String> path = new ArrayList<>(); while (state != null) { path.add(Arrays.toString(state.items)); state = state.parent; } Collections.reverse(path); for (String s : path) { System.out.println(s); } } public static void main(String[] args) { solve(); } } ``` 在上述代码中,我们首先定义了人羊狼菜过河问题的初始状态和目标状态,以及人、羊、狼、菜的编号。然后,我们定义了一个`State`类来表示人羊狼菜过河问题的状态,包括当前状态下的物品位置、船的位置和父状态。`State`类还包括了判断当前状态是否为目标状态、获取下一步状态的方法以及判断状态是否合法的方法。 接下来,我们使用深度优先搜索算法来解决人羊狼菜过河问题。我们首先定义了一个栈和一个HashSet,用于存储当前搜索路径和已经访问过的状态。然后,我们从初始状态开始搜索,每次从栈中弹出一个状态,并查找该状态下所有可能的下一步状态。如果某个下一步状态是合法的且之前没有访问过,那么将其压入栈中,并将其添加到已访问状态的HashSet中。如果找到了目标状态,则打印求解路径;否则,输出“No solution found!”。最后,在`main`方法中调用`solve`方法来求解人羊狼菜过河问题。 需要注意的是,上述代码只是一个简单的示例,还有许多可以改进的地方,例如使用广度优先搜索算法、优化搜索过程等等。
评论 52
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值