问题描述:
现在有很多制造商都在卖扫地机器人,它非常有用,能为忙碌的我们分担家务负担。不过我们也很难理解为什么扫地机器人有时候会反复清扫某一个地方。
假设有一款不会反复清扫同一个地方的机器人,它只能前后左右移动。举个例子,如果第1 次向后移动,那么连续移动3 次时,就会有以下9 种情况( 下图)。又因为第1 次移动可以是前后左右4 种情况,所以移动3 次时全部路径有9×4 = 36 种。
※ 最初的位置用0 表示,其后的移动位置用数字表示。
解题思路:使用深度优先搜索
详解:
假设起始点的坐标为(0,0),机器人的第一步选择有四种:(0,1),(0,-1),(1,0),(-1,0)。
从第一步中挑选一个坐标(0,1),机器人的第二步选择有三种:(1,1),(-1,1),(0,2),(0,0)(重复)
。。。。。。
以此类推,每步起始坐标的上、下、左、右没有被占就可以走。
代码:
public class Roomba {
private class Location {
private int x = 0;
private int y = 0;
public int getX() {
return x;
}
public int getY() {
return y;
}
public Location() {
}
public Location(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
return x + y;
}
@Override
public boolean equals(Object obj) {
Location tmp = (Location) obj;
return x == tmp.x && y == tmp.y;
}
}
//历史位置
private Set historyLocation = new HashSet();
//移动步数
private int moveStap = 12;
//总共路径
private int countPath = 0;
public void method1(Location startLocaiton, int step) {
int nextStep = step + 1;
historyLocation.add(startLocaiton);
if (step < moveStap) {
//移动:x+1
Location xAdd1 = new Location(startLocaiton.getX() + 1, startLocaiton.getY());
if (!historyLocation.contains(xAdd1)) {
method1(xAdd1, nextStep);
historyLocation.remove(xAdd1);
if (step == moveStap - 1) countPath++;
}
//移动:x-1
Location xSub1 = new Location(startLocaiton.getX() - 1, startLocaiton.getY());
if (!historyLocation.contains(xSub1)) {
method1(xSub1, nextStep);
historyLocation.remove(xSub1);
if (step == moveStap - 1) countPath++;
}
//移动:y+1
Location yAdd1 = new Location(startLocaiton.getX(), startLocaiton.getY() + 1);
if (!historyLocation.contains(yAdd1)) {
method1(yAdd1, nextStep);
historyLocation.remove(yAdd1);
if (step == moveStap - 1) countPath++;
}
//移动:y-1
Location ySub1 = new Location(startLocaiton.getX(), startLocaiton.getY() - 1);
if (!historyLocation.contains(ySub1)) {
method1(ySub1, nextStep);
historyLocation.remove(ySub1);
if (step == moveStap - 1) countPath++;
}
}
}
@Test
public void test1() {
Location startLocation = new Location();
method1(startLocation, 0);
System.out.println(countPath);
}
}