河的一边有三个人和三个鬼,河中有一小船,每次最多能乘坐2个人或鬼,而且至少要有一个人或鬼船才能行驶。请设计一种算法,把人和鬼都送到对岸。注:不论是在河边、船上,如果人鬼数量相同,则鬼和人能和谐相处,鬼不吃人,否则,鬼吃掉人。要求算法能给出整个运送过程,包括每次船行驶的方向(是驶向对岸还是返回),船上的人和鬼数量。
相信大家都接触过这个问题,我在论坛也参考过一些算法,但是觉得效率不是很高
我自己有个想法就是把所有过河的策略都列出来,形成一棵树(每个方法代表一个结点),然后通过搜索找出符合要求的结点,可以通过广度搜索和深度搜索,最后符合的结点为最后方法。但是想法是有,如何用JAVA语言编写该算法,符合题目要求不知道从何如何入手,请大家发表下意见帮帮忙,最好有些代码参考下,谢谢
相信大家都接触过这个问题,我在论坛也参考过一些算法,但是觉得效率不是很高
我自己有个想法就是把所有过河的策略都列出来,形成一棵树(每个方法代表一个结点),然后通过搜索找出符合要求的结点,可以通过广度搜索和深度搜索,最后符合的结点为最后方法。但是想法是有,如何用JAVA语言编写该算法,符合题目要求不知道从何如何入手,请大家发表下意见帮帮忙,最好有些代码参考下,谢谢
由于是边想边写的,可能有些混乱..
凑活看看吧,希望能给你些思路
public class Test { public static void main(String[] args) {
Game game = new Game();
game.cycle();
for (int i = 0; i < game.getList().size(); i++) {
System.out.println(game.getList().get(i).toString());
}
}}public class Side implements Cloneable { public final static int PERSON = 0; public final static int GHOST = 1; public final static int NO = 0; public final static int YES = 1; private int presonQty = 0; private int ghostQty = 0; private int hasBoat = 0; Side() {
} Side(int preson, int ghost, int boat) {
this.presonQty = preson;
this.ghostQty = ghost;
this.hasBoat = boat;
} public int getHasBoat() {
return hasBoat;
} public void setHasBoat(int boat) {
this.hasBoat = boat;
} public int getGhostQty() {
return ghostQty;
} public void setGhostQty(int ghost) {
this.ghostQty = ghost;
} public int getPresonQty() {
return presonQty;
} public void setPresonQty(int preson) {
this.presonQty = preson;
} public boolean addOneObject(int presonOrGhost) {
boolean forReturn = true;
if (presonOrGhost == 0) {
this.setPresonQty(this.getPresonQty() + 1);
}
if (presonOrGhost == 1) {
this.setGhostQty(this.getGhostQty() + 1);
}
return forReturn;
} public boolean removeOneObject(int presonOrGhost) {
boolean forReturn = true;
if (presonOrGhost == Side.PERSON) {
this.setPresonQty(this.getPresonQty() - 1);
if (this.getPresonQty() < 0) {
forReturn = false;
}
}
if (presonOrGhost == Side.GHOST) {
this.setGhostQty(this.getGhostQty() - 1);
if (this.getGhostQty() < 0) {
forReturn = false;
}
}
return forReturn;
} public void changeBoat() {
this.setHasBoat((this.getHasBoat() + 1) % 2);
} public Object clone() {
Side side = null;
try {
side = (Side) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return side;
} public String toString() {
return "{preson:" + presonQty + ",ghost:" + ghostQty + ",isHasBoat:"
+ (hasBoat == Side.YES ? "Y" : "N") + "}";
} public boolean isSafe() {
if (this.getPresonQty() * (this.getPresonQty() - this.getGhostQty()) < 0) {
return false;
}
return true;
} public boolean equals(Object side) {
return this.getPresonQty() == ((Side) side).getPresonQty()
&& this.getGhostQty() == ((Side) side).getGhostQty()
&& this.getHasBoat() == ((Side) side).getHasBoat();
}
}
public class Cross implements Cloneable { private Side sideA = new Side(3, 3, 1); private Side sideB = new Side(0, 0, 0); private int[] presonOrGhosts = null; public boolean cross(int[] presonOrGhosts) {
this.setPresonOrGhosts(presonOrGhosts);
int presonQty = 0;
int ghostQty = 0;
boolean forReturn = true;
for (int i = 0; i < presonOrGhosts.length; i++) {
if (presonOrGhosts[i] == Side.PERSON) {
presonQty++;
}
if (presonOrGhosts[i] == Side.GHOST) {
ghostQty++;
}
forReturn = this.crossOneObject(presonOrGhosts[i]) && forReturn;
}
this.changeSide();
forReturn = sideA.isSafe() && forReturn;
forReturn = sideB.isSafe() && forReturn;
forReturn = isSafeOnBoat(presonQty, ghostQty) && forReturn;
return forReturn;
} public boolean crossOneObject(int presonOrGhost) {
boolean forReturn = true;
if (this.sideA.getHasBoat() == Side.YES) {
forReturn = this.getSideA().removeOneObject(presonOrGhost)
&& forReturn;
forReturn = this.getSideB().addOneObject(presonOrGhost)
&& forReturn;
}
if (this.sideB.getHasBoat() == Side.YES) {
forReturn = this.getSideB().removeOneObject(presonOrGhost)
&& forReturn;
forReturn = this.getSideA().addOneObject(presonOrGhost)
&& forReturn;
}
return forReturn;
} public boolean isSafeOnBoat(int presonQty, int ghostQty) {
if (presonQty * (presonQty - ghostQty) < 0) {
return false;
}
return true;
} public String toString() {
String forReturn = "";
String way1 = "";
String way2 = "";
if (sideA.getHasBoat() == Side.YES) {
way1 = " <<<-------";
way2 = "<<<------- ";
} else {
way1 = " ------->>>";
way2 = "------->>> ";
}
forReturn = forReturn + "sideA:" + sideA.toString() + ";sideB:"
+ sideB.toString();
int presonQty = 0;
int ghostQty = 0;
if (this.getPresonOrGhosts() != null) {
for (int i = 0; i < this.getPresonOrGhosts().length; i++) {
if (this.getPresonOrGhosts()[i] == Side.PERSON) {
presonQty++;
}
if (this.getPresonOrGhosts()[i] == Side.GHOST) {
ghostQty++;
}
}
forReturn = way1 + "boat{preson:" + presonQty + ",ghost:" + ghostQty
+ "}" + way2 + " \n" + forReturn;
}
return forReturn;
} public void changeSide() {
this.getSideA().changeBoat();
this.getSideB().changeBoat();
} public Side getSideA() {
return sideA;
} public void setSideA(Side sideA) {
this.sideA = sideA;
} public Side getSideB() {
return sideB;
} public void setSideB(Side sideB) {
this.sideB = sideB;
} public int[] getPresonOrGhosts() {
return presonOrGhosts;
} public void setPresonOrGhosts(int[] presonOrGhosts) {
this.presonOrGhosts = presonOrGhosts;
} public Object clone() {
Cross cross = null;
try {
cross = (Cross) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
cross.setSideA((Side) cross.getSideA().clone());
cross.setSideB((Side) cross.getSideB().clone());
if (cross.getPresonOrGhosts() == null) {
cross.setPresonOrGhosts(null);
} else {
int[] presonOrGhostsCopy = new int[cross.getPresonOrGhosts().length];
System.arraycopy(cross.getPresonOrGhosts(), 0, presonOrGhostsCopy,
0, presonOrGhostsCopy.length);
cross.setPresonOrGhosts(presonOrGhostsCopy);
}
return cross;
} public boolean equals(Object cross) {
return this.getSideA().equals(((Cross) cross).getSideA())
&& this.getSideB().equals(((Cross) cross).getSideB());
}
}import java.util.LinkedList;public class Game {
private LinkedList list = new LinkedList(); private int[] presonOrGhosts = null; private Cross cross = new Cross(); Game() {
list.add(this.cross.clone());
} public int[] combination(int qty, int[] previousArray) {
int temp = 0; int[] forReturn = null;
if (previousArray != null) {
forReturn = new int[previousArray.length];
System.arraycopy(previousArray, 0, forReturn, 0, forReturn.length);
}
for (int i = 0; previousArray != null && i < previousArray.length; i++) {
if (previousArray[i] == Side.PERSON) {
forReturn[i] = Side.GHOST;
temp = 1;
break;
}
}
if (temp == 0) {
if (previousArray == null) {
forReturn = new int[] { Side.PERSON };
} else if (previousArray.length == qty) {
forReturn = null;
} else {
forReturn = new int[previousArray.length + 1];
for (int i = 0; i < forReturn.length; i++) {
forReturn[i] = Side.PERSON;
}
}
}
return forReturn;
} public void cycle() {
presonOrGhosts = combination(2, presonOrGhosts);
if (presonOrGhosts != null) {
if (!cross.cross(presonOrGhosts)) {
cross.cross(presonOrGhosts);
// System.out.println("" + list.size() + ",NO");
} else {
int sign = 0;
for(int i=0;i<list.size();i++)
{
if(this.cross.equals(list.get(i)))
{
cross.cross(presonOrGhosts);
sign = 1;
// System.out.println("" + list.size() + ",NO");
break;
}
}
if(sign==0)
{
list.add(cross.clone());
presonOrGhosts = null;
// System.out.println("" + list.size() + ",YES");
}
}
} else {
presonOrGhosts = ((Cross) list.getLast()).getPresonOrGhosts();
list.removeLast();
cross = (Cross) ((Cross) list.getLast()).clone();
// System.out.println("" + list.size() + ",BACK");
}
if (!isOver()) {
this.cycle();
}
} public boolean isOver() {
if (this.cross.getSideA().getPresonQty() == 0
&& this.cross.getSideA().getGhostQty() == 0
&& this.cross.getSideA().getHasBoat() == Side.NO) {
return true;
} else {
return false;
}
} public LinkedList getList() {
return list;
} public void setList(LinkedList list) {
this.list = list;
}
}