考试中遇到的一道逻辑问题:一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,则不会发生这种问题。编程解决猫狗鱼过河问题。
出现的涉及变化的对象:两岸,动物,老农
两岸包含动物,可以用集合,方便两岸的动物的增删。
老农只有两种状态,用Boolean,左岸TRUE,右岸FALSE。
定义一个移动动物的方法,移动就需要判断知道过河的规则
过河规则:
- 判断两岸是否冲突
- 禁止带回刚带来的动物
- 左岸——右岸必须带一个动物,右岸——左岸可带可不带
1,2规则是两岸带动物的共同规则,抽取为移动动物的方法
3是两岸的不同规则。在过河中控制
public class Test {
//两岸的集合left,right
List<String> left = new ArrayList<String>();
List<String> right = new ArrayList<String>();
//老农person定义为Boolean,左岸TRUE,右岸FALSE
Boolean person = true;
//take记录运送的动物
String take = "";
public Test() {
left.add("dog");
left.add("cat");
left.add("fish");
}
public boolean isSafe(List<String> river) {
//当某岸动物大于一只,并且有猫是不安全,返回FALSE
if (river.size()>1 & river.contains("cat")) {
return false;
}
return true;
}
public void move(List<String> del, List<String> save, boolean p) {
Random random = new Random(); //老农随机带走一直动物
int index = random.nextInt(del.size());
//移动随机抽取的动物
String leftstr = del.remove(index);
save.add(leftstr);
//判断是否和上次带过来的动物一样
if (take.equals(leftstr)) {
del.add(leftstr);
save.remove(leftstr);
}else {
//判断移动后是否本岸是否安全
if (isSafe(del)) {
take = leftstr;
System.out.println(take);
person = !p;
} else {
del.add(leftstr);
save.remove(leftstr);
}
}
}
public void moveAnimal() {
//当左岸的动物都带走完,停止循环
while (left.size()>0) {
//判断农夫在左岸还是右岸
if (person==true) {
move(left, right, person);
}
if (person==false) {
//右岸安全的话,农夫不带动物回到左岸
if (isSafe(right)) {
System.out.println("老农一个人返回左岸");
person = true;
}else {
move(right, left, person);
}
}
}
}
public static void main(String[] args) {
Test test = new Test();
test.moveAnimal();
}
}