栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

算法趣题-Q26

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

算法趣题-Q26

一、问题描述

二、问题分析

        书中的解题思路为用二维数组模拟,但是实际上我们只关注空白车位和目标车的位置,那么没有必要使用数组存储其他车的状态,只需要将空白车位和目标车的位置记录下来就可以,然后就是广度遍历,如Python实现。

        另一种解题思路同样建立在以存储两点位置的基础上,对于空白车位的移动目标位置是有规律的,其必然会与目标车的当前位置相邻,且是靠近最终出口位置的,所以我们可以直接根据空白车位的移动规律设计代码,如C/C++实现。

三、代码实现 1.C/C++实现
#include 
#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;
}
2.Python实现
# 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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1019596.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号