华为OD机试真题-路口最短时间问题【C++】

题目

假定街道是棋盘型的,每格距离相等,车辆通过每格街道需要时间均为 timePerRoad;街道的街口(交叉点)有交通灯,灯的周期T(=lights[row][col])各不相同;车辆可直行、左转和右转,其中直行和左转需要等相应T时间的交通灯才可通行,右转无需等待。
现给出 n*m 个街口的交通灯周期,以及起止街口的坐标,计算车辆经过两个街口的最短时间。
其中:
1)起点和终点的交通灯不计入时间,且可以任意方向经过街口
2)不可超出 n*m 个街口,不可跳跃,但边线也是道路(即 lights[0][0] -> lights[0][1] 是有效路径)

入口函数定义:
/**
* lights : n*m 个街口每个交通灯的周期,值范围[0,120],n和m的范围为[1,9]
* timePerRoad : 相邻两个街口之间街道的通过时间,范围为[0,600]
* rowStart : 起点的行号
* colStart : 起点的列号
* rowEnd : 终点的行号
* colEnd : 终点的列号
* return : lights[rowStart][colStart] 与 lights[rowEnd][colEnd] 两个街口之间的最短通行时间
*/
int calcTime(int[][] lights,int timePerRoad,int rowStart,int colStart,int rowEnd,int colEnd)

输入描述

第一行输入 n 和 m,以空格分隔

之后 n 行输入 lights矩阵,矩阵每行m个整数,以空格分隔

之后一行输入 timePerRoad

之后一行输入 rowStart colStart,以空格分隔

最后一行输入 rowEnd colEnd,以空格分隔

输出描述

lights[rowStart][colStart] 与 lights[rowEnd][colEnd] 两个街口之间的最短通行时间

用例

输入

3 3
1 2 3
4 5 6
7 8 9
60
0 0
2 2

输出

245

说明

行走路线为 (0,0) -> (0,1) -> (1,1) -> (1,2) -> (2,2) 走了4格路,2个右转,1个左转,共耗时 60+0+60+5+60+0+60=245

以下是C++的非递归解法,递归虽然能解该题,但是实际项目过程中,好的编码规范一律不允许使用递归,因为它会带来非常多的不确定性隐患。 

#include <stdio.h>
#include <map>
#include <vector>
#include <iostream>
#include <string>
using namespace std;


class CRoadPoint
{
	public:
	static void SetPointMax(unsigned int x, unsigned int y)
	{
		xMax = x;
		yMax = y;
	}


	CRoadPoint(unsigned int x, unsigned int y,unsigned int uiWaitFromParent,bool bCorrect = false)
		:m_uiWaitFromParent(uiWaitFromParent),m_pGamePointParent(NULL),m_bCorrectPoint(bCorrect)
	{
		if (x <= xMax && y <= yMax)
		{
			m_uiPointX= x;
			m_uiPointY = y;
			m_bCorrectPoint = true;
		}
	}
	bool operator==(const CRoadPoint& oPointRight)
	{
		if(this->m_uiPointX == oPointRight.m_uiPointX && this->m_uiPointY == oPointRight.m_uiPointY)
		{
			return true;
		}
		return false;
	}
	string PointOutput()
	{
		char strTemp[100];
		memset(strTemp,0x00,100);
		sprintf(strTemp,"Point(x:%d,y:%d) ",m_uiPointX,m_uiPointY);
		return strTemp;
	}
	string PointOutputToRoot()
	{
		string strOutPut = PointOutput();
		CRoadPoint* pTemp = m_pGamePointParent;
		while(pTemp != NULL)
		{
			strOutPut = pTemp->PointOutput() + strOutPut;
			pTemp = pTemp->m_pGamePointParent;
		}
		return strOutPut;
	}
	unsigned int PointWaitToRoot()
	{
		unsigned int uiWait = m_uiWaitFromParent;
		CRoadPoint* pTemp = m_pGamePointParent;
		while(pTemp != NULL)
		{
			uiWait += pTemp->m_uiWaitFromParent;
			pTemp = pTemp->m_pGamePointParent;
		}
		return uiWait;
	}
	bool IsNewPoint(const CRoadPoint& oNewPoint)
	{
		if (*this == oNewPoint)
		{
			return false;
		}
		bool bNewPoint(true);
		CRoadPoint* pTemp = m_pGamePointParent;
		while(pTemp != NULL)
		{
			if ((*pTemp) == oNewPoint)
			{
				bNewPoint = false;
				break;
			}
			pTemp = pTemp->m_pGamePointParent;
		}
		return bNewPoint;
	}
	public:
	CRoadPoint* m_pGamePointParent;
	unsigned int m_uiPointX;
	unsigned int m_uiPointY;
	unsigned int m_uiWaitFromParent;
	bool	m_bCorrectPoint;
	static unsigned int xMax;
	static unsigned int yMax;

	
};
unsigned int CRoadPoint::xMax = 0;
unsigned int CRoadPoint::yMax = 0;
//入口函数定义:
/**
* lights : n*m 个街口每个交通灯的周期,值范围[0,120],n和m的范围为[1,9]
* timePerRoad : 相邻两个街口之间街道的通过时间,范围为[0,600]
* rowStart : 起点的行号
* colStart : 起点的列号
* rowEnd : 终点的行号
* colEnd : 终点的列号
* return : lights[rowStart][colStart] 与 lights[rowEnd][colEnd] 两个街口之间的最短通行时间
*/
int calcTime(int lights[][10],int timePerRoad,int rowStart,int colStart,int rowEnd,int colEnd)
{
	CRoadPoint oPointStart(rowStart,colStart,0);
	CRoadPoint oPointEnd(rowEnd,colEnd,0);
	typedef vector<CRoadPoint> VectorGamePoint;
	map<int,VectorGamePoint> mapFind;
	VectorGamePoint vecPoint;
	VectorGamePoint vecResult;
	vecPoint.push_back(oPointStart);
	mapFind[0] = vecPoint;

	map<int,VectorGamePoint>::iterator iterMapFind = mapFind.end();
	bool bFindBaby(false);
	while (!bFindBaby)
	{
		iterMapFind = mapFind.end();
		iterMapFind--;
		VectorGamePoint vecPointTemp = iterMapFind->second;
		VectorGamePoint vecNewPoin;

		for (size_t sCurSize = 0 ; sCurSize < vecPointTemp.size();sCurSize++)
		{
			CRoadPoint oPointTemp = vecPointTemp[sCurSize];
			if (oPointTemp == oPointEnd)
			{
				bFindBaby = true;
				vecResult.push_back(oPointTemp);
				continue;
			}
			else if (bFindBaby == false)
			{
				bool bEnable(false);
				unsigned int uiWait = lights[oPointTemp.m_uiPointX][oPointTemp.m_uiPointY];
				if (oPointTemp.m_uiPointX > 0)
				{
					//left
					CRoadPoint oPointLeft(oPointTemp.m_uiPointX - 1,oPointTemp.m_uiPointY,uiWait);
					oPointLeft.m_pGamePointParent = &((iterMapFind->second)[sCurSize]);
					bool bEnable = oPointLeft.m_bCorrectPoint;
					if (bEnable == true && oPointTemp.IsNewPoint(oPointLeft))
					{
						vecNewPoin.push_back(oPointLeft);
					}

				}
				if (oPointTemp.m_uiPointX < CRoadPoint::xMax)
				{
					//right
					
					CRoadPoint oPointRight(oPointTemp.m_uiPointX + 1,oPointTemp.m_uiPointY,0);
					bool bEnable = oPointRight.m_bCorrectPoint;

					oPointRight.m_pGamePointParent = &((iterMapFind->second)[sCurSize]);
					if (bEnable == true && oPointTemp.IsNewPoint(oPointRight))
					{
						vecNewPoin.push_back(oPointRight);
					}
				}
				if (oPointTemp.m_uiPointY < CRoadPoint::yMax)
				{
					//top
					CRoadPoint oPointTop(oPointTemp.m_uiPointX,oPointTemp.m_uiPointY + 1,uiWait);
					oPointTop.m_pGamePointParent = &((iterMapFind->second)[sCurSize]);
					bool bEnable = oPointTop.m_bCorrectPoint;
					if (bEnable == true && oPointTemp.IsNewPoint(oPointTop))
					{
						vecNewPoin.push_back(oPointTop);
					}
				}
				if (oPointTemp.m_uiPointY > 0)
				{
					//Bottom
					CRoadPoint oPointBottom(oPointTemp.m_uiPointX,oPointTemp.m_uiPointY - 1,uiWait);
					oPointBottom.m_pGamePointParent = &((iterMapFind->second)[sCurSize]);
					bool bEnable = oPointBottom.m_bCorrectPoint;
					if (bEnable == true && oPointTemp.IsNewPoint(oPointBottom))
					{
						vecNewPoin.push_back(oPointBottom);
					}
				}


			}
		}
		if (bFindBaby == false)
		{
			if (!vecNewPoin.empty())
			{
				mapFind[mapFind.size()] = vecNewPoin;
			}
			else
			{
				break;
			}

		}

	}

	unsigned int uiDistanse = mapFind.size() - 1;
	unsigned int uiCost = uiDistanse * timePerRoad;
	unsigned int uiCostMin(0);
	for(size_t sCurSize = 0;sCurSize < vecResult.size();sCurSize++)
	{
		unsigned int uiWait = vecResult[sCurSize].PointWaitToRoot();
		if (uiCostMin == 0)
		{
			uiCostMin = uiCost + uiWait;
			cout << vecResult[sCurSize].PointOutputToRoot() << endl;
			cout << "基准最短耗时:" << uiCostMin << endl;
		}
		else if (uiCostMin > uiCost + uiWait)
		{
			uiCostMin = uiCost + uiWait;
			cout << vecResult[sCurSize].PointOutputToRoot() << endl;
			cout <<  "发现更短耗时:" << uiCostMin << endl;
		}

	}

	return uiCostMin;
}

int main()
{
    int lights[10][10]={21,32,43,24,15,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,2,3,4,5,6,7,38,9,10,11,32,13,14,35,46,37,38,29,10,1,2,3,4,5,6,7,8,9,10,11,12,23,34,5,16,17,18,19,8,1,2,3,4,5,26,7,8,19,10,11,12,13,14,15,33,17,18,22,20,1,2,3,24,5,6,7,18,9,10,11,12,13,14,15,16,17,18,19,20};
	CRoadPoint::SetPointMax(9,9);
	int timePerRoad = 8;
	int rowStart = 8;
	int colStart = 7;
	int rowEnd = 2;
	int colEnd = 3;
	int iRet = calcTime(lights, timePerRoad, rowStart, colStart, rowEnd, colEnd);
	if (iRet > 0)
	{
		cout << "通过两个路口最短时间是:"<< iRet << endl;
	}
    return 0;
}
首先,在选择服务中心的最佳位置时,我们需要考虑各种因素,包括人口密度、交通便利性、基础设施和竞争对手等。对于华为OD项目来说,我会推荐选址在人口密度相对较高的城市中心地带。这样可以确保服务中心能够覆盖到更多的用户群体,提高服务的便利性和覆盖面。 其次,交通便利性也是选择最佳位置的重要考量因素。一个位于交通枢纽地带的服务中心可以更容易地接触到周围城市的用户,减少用户的前往成本和时间。同时,也方便快速调度和配送产品,提高服务的效率和时效性。 此外,基础设施的完善也是一个重要的考虑因素。一个服务中心应该有稳定的电力、通讯和网络设施,以保证服务的持续性和稳定性。另外,周边商业设施和生活设施的配套也能吸引更多的顾客和员工,提高服务中心的吸引力和竞争力。 最后,对竞争对手的考虑也至关重要。在选择服务中心的位置时,需要做好竞争对手的地域分析,避免选择在竞争对手的聚集地带,同时也要考虑如何在竞争对手密集的区域提供更优质的服务和更吸引人的特色,以获得竞争优势。 综上所述,选择服务中心最佳位置需要全面考虑各种因素,包括人口密度、交通便利性、基础设施和竞争对手,这样才能确保服务中心能够更好地为用户提供服务,同时也能提高企业的竞争力和影响力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值