书中的解题思路为用二维数组模拟,但是实际上我们只关注空白车位和目标车的位置,那么没有必要使用数组存储其他车的状态,只需要将空白车位和目标车的位置记录下来就可以,然后就是广度遍历,如Python实现。
另一种解题思路同样建立在以存储两点位置的基础上,对于空白车位的移动目标位置是有规律的,其必然会与目标车的当前位置相邻,且是靠近最终出口位置的,所以我们可以直接根据空白车位的移动规律设计代码,如C/C++实现。
三、代码实现 1.C/C++实现#include2.Python实现#include #include #include #include #include #include using namespace std; typedef pair Point; bool point_swap(Point& p1, Point& p2) { // 判断是否可以交换(相邻点才可以互换) if (abs(p1.first - p2.first) + abs(p1.second - p2.second) != 1) return false; swap(p1.first, p2.first); swap(p1.second, p2.second); return true; } int get_next_blank(Point& blank, const Point& cur, const Point& obj) { int v_det = (obj.second - cur.second > 0) ? 1 : -1; int h_det = (obj.first - cur.first > 0) ? 1 : -1; // 两个可能的最优点 Point tmp1 = make_pair(cur.first, cur.second + v_det); Point tmp2 = make_pair(cur.first + h_det, cur.second); // 计算两个新的空白点到原来位置的距离 int dis1, dis2; if (cur.first == blank.first) // 三点一线的情况 dis1 = abs(blank.second - tmp1.second) + 2; else dis1 = abs(blank.second - tmp1.second) + abs(blank.first - tmp1.first); if (cur.second == blank.second) // 三点一线的情况 dis2 = abs(blank.first - tmp2.first) + 2; else dis2 = abs(blank.first - tmp2.first) + abs(blank.second - tmp2.second); // 贪心,选择最小距离 // 空白车位的两个候选位置与出口的距离基本上都是相同的,但是在最后一步时会有区别 if (dis1 + abs(obj.first - tmp1.first) + abs(obj.second - tmp1.second) >= dis2 + abs(obj.first - tmp2.first) + abs(obj.second - tmp2.second)) { blank.first = tmp2.first; blank.second = tmp2.second; return dis2; } else { blank.first = tmp1.first; blank.second = tmp1.second; return dis1; } } int main() { const int MAX_L = 10; const int MAX_W = 10; Point cur, obj, blank; cur = make_pair(1, 1); obj = make_pair(MAX_L, MAX_W); blank = make_pair(MAX_L, MAX_W); int steps = 0; while (abs(obj.first - cur.first) + abs(obj.second - cur.second)) { steps += get_next_blank(blank, cur, obj); if (point_swap(cur, blank)) steps++; } cout << steps << endl; return 0; }
# coding = utf-8
MAX_X = 10
MAX_Y = 10
history = [(1, 1, MAX_X, MAX_Y), ] # 存放遍历历史, 前两个值为目标车坐标,后两个值为空白位置坐标
history2level = [0, ] # 存放对应遍历的遍历深度
det_x = [0, 1, 0, -1]
det_y = [1, 0, -1, 0]
def get_next_level(index):
cur_level = history2level[index]
blank = history[index]
for i in range(4):
tmp_b = [blank[2] + det_x[i], blank[3] + det_y[i]]
if tmp_b[0] > 10 or tmp_b[1] > 10 or tmp_b[0] < 0 or tmp_b[1] < 0: # 越界
continue
if blank[0] == tmp_b[0] and blank[1] == tmp_b[1]: # 空白格移动到目标车,相当于两个位置交换
tmp_h = (blank[2], blank[3], tmp_b[0], tmp_b[1])
else:
tmp_h = (blank[0], blank[1], tmp_b[0], tmp_b[1])
if tmp_h not in history:
history.append(tmp_h)
history2level.append(cur_level + 1)
pass
def search():
index = 0
level = 0
while history[index][0] != MAX_X or history[index][1] != MAX_Y:
get_next_level(index)
index += 1
level = history2level[index]
return level
if __name__ == '__main__':
print(search())
pass



