华为内部员工测评题——地铁站最佳路线推荐

背景概述

?城市的地铁网络由多条线路组成

?每条线路上有多个车站,线路自身没有交叉点

?线路间交叉或重叠时,共用车站,在这些车站上可相互换乘

?每条线路都是双向行车

?线路有两种:I形线和O形线

–I形线有两个端点,乘客在端点处只能乘坐开往另外一端的地铁,在非端点处则有两个方向可选择。(如图中8号线)

–O形线所有车站形成环,没有端点,乘客在任一站都有两个方向可选择。(如图中4号线)

功能需求

在地铁网络中任选一站为起点,任选另一站为终点,中途可换乘,要求输出

1)最短路线长度:从起点到终点经过的最少站数(站数计算不含起点,含终点)

2)最短路线:满足最短路线长度要求的所有路线(可能有多条路线,每条路线从起点到终点顺序输出途经的所有站点,包括起点和终点)

3)最优路线:换乘次数最少的最短路线(可能有多条路线)

输入说明

地铁网络中的每一个站点用一个唯一的ID标识,ID是一个32位正整数;

一次输入一条线路,线路表示为一个站点ID数组;

–例如{2, 3, 6, 9, 10},表示这是一条I形线,2和10为两端,数组元素顺序和从一端到另一端途经站点的顺序一致;

–例如{1, 3, 6, 7, 4, 1},首尾站点一样,表示这是一条O形线,数组元素顺序和从站点1出发按某方向绕行一圈途经站点的顺序一致;

两条线路中出现了相同站点(如上面的3、6),表示两条线路在这些站点可相互换乘。

示例

某城市的地铁信息,如图

Line1:{1,2,3,4,5};

Line2:{1,10,9,7,6};

Line3:{5,7,8};

Line4:{11,5};

从起点站1到终点站11

1)最短路线长度是5

2)最短路线有2条,分别是{1, 2, 3, 4,5,11}和{1,10,9,7,5,11}

3)最优路线有1条:{1, 2, 3, 4,5,11} (换乘一次)

这种题非常实用,类似百度地图查公交车一样,距离最短及换乘次数最少之类的,算是图论的范畴,找到最短路径长度并不难,但要保存起来还必须得深度搜索,在华为OJ上属于最难的一种分级(挑战),一般华为招聘机试只有三道题(初级,中级,高级各一道),不会考这么难的题的。至于最少换乘方案还没做好,先把代码存在这里,后面继续完善,欢迎回帖交流~

#include<iostream>
//#include<string>
//#include<algorithm>
//#include<cmath>
#include<vector>
#include<queue>
//#include<stack>
//#include<iomanip>
using namespace std;

#define MAX 535
int flag[MAX];
vector<int>station_reach[MAX];
static vector<int>myfront[MAX];
/*******************************************************************************************************************
函数说明: 增加某条地铁线路
函数原型: void AddLine(unsigned int LineNo, unsigned int StationNum ,unsigned  int *pStationArray);
输入参数:
           LineNo        地铁线路号;
           StationNum    该条地铁线中的站点数目,由调用者保证不小于2;
           pStationArray 该条地铁线的所有站点信息,pStationArray指向的存储空间在函数外会被释放,请自行申请存储空间;
输出参数: 无
返回值  : 无
********************************************************************************************************************/
void AddLine(unsigned int LineNo, unsigned int StationNum ,unsigned  int *pStationArray)
{
    /* 在这里实现功能 */

	int i;
	for(i=1;i<StationNum;i++)
	{
		station_reach[pStationArray[i]].push_back(pStationArray[i-1]);
		station_reach[pStationArray[i-1]].push_back(pStationArray[i]);
	}

    return;

}

/*********************************************************************************************************************
函数说明:计算从起点站到终点站的最短路线长度
函数原型:int CalcMinPathLen(unsigned int SrcStation, unsigned int DesStation);
输入参数:
          SrcStation  起点站;
          DesStation 终点站;
输出参数:无
返回值  :
          起点站到终点站的最短路线长度
          -1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等)
**********************************************************************************************************************/
int CalcMinPathLen(unsigned int SrcStation, unsigned int DesStation)
{

    /* 在这里实现功能 */
	if(SrcStation==DesStation)return -1;
	int i,j,newsta;
	int minlen=1,count=0;
	queue<int>qsta;
   /*
	for(i=1;i<11;i++)
	{
		cout<<i<<"站"<<":";
		for(j=0;j<station_reach[i].size();j++)
			cout<<station_reach[i][j]<<" ";
		cout<<endl;
	}
	cout<<endl;
*/
	memset(flag,0,sizeof(flag));

	for(i=0;i<station_reach[SrcStation].size();i++)
	{
		if(station_reach[SrcStation][i]==DesStation)return minlen;
		qsta.push(station_reach[SrcStation][i]);
		//count++;
	}
	flag[SrcStation]=1;
	int ss=qsta.size();
	while(!qsta.empty())
	{

		minlen++;
		count=qsta.size();
		while(count--){
			newsta=qsta.front();
			flag[newsta]=1;
			for(i=0;i<station_reach[newsta].size();i++)
			{
				if(station_reach[newsta][i]==DesStation)return minlen;
				if(flag[station_reach[newsta][i]]==0)qsta.push(station_reach[newsta][i]);
			}
			qsta.pop();
		}
	}
	if(qsta.empty()) return -1;

    return 0;

};

/**********************************************************************************************************
函数说明:输出从起点站到终点站的最短路线
函数原型:int SearchMinPathes(unsigned int SrcStation,
                              unsigned int DesStation,
                              unsigned int* pPathNum,
                              unsigned int* pPathLen,
                              unsigned int **ppPathes);
输入参数:
          SrcStation 起点站;
          DesStation 终点站;
          Output Param
          pPathNum 最短路线条数;
          pPathLen  最短路线长度;
          ppPathes 存储最短路线的内存地址,内存空间在本函数内申请,调用者释放,内存空间的存储格式请见PPT要求;
返回值  :
          0 :成功
          -1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等)

************************************************************************************************************/
void dfs(unsigned int SrcStation,
         unsigned int DesStation,
		 unsigned int minlen,
		 unsigned int *pPathLen,
         unsigned int* pPathNum,
		 unsigned int **pPathes
		 )
{
	int i,j;

	if(minlen==1)
	{
		if(myfront[DesStation][0]==SrcStation)
		{
			(*pPathNum)++;
			pPathes[(*pPathNum)-1]=(unsigned int *)malloc((*pPathLen+1)*sizeof(unsigned int));
			memset(pPathes[(*pPathNum)-1],0,(*pPathLen+1)*sizeof(unsigned int));
			pPathes[(*pPathNum)-1][minlen-1]=SrcStation;
			pPathes[(*pPathNum)-1][minlen]=DesStation;

			//cout<<DesStation<<" "<<minlen<<" "<<*pPathNum<<endl;
		}
		return;
	}

	for(i=0;i<myfront[DesStation].size();i++)
	{
		j=myfront[DesStation][i];
		//cout<<j<<" "<<minlen-1<<endl;
		dfs(SrcStation,j,minlen-1,pPathLen,pPathNum,pPathes);
		pPathes[(*pPathNum)-1][minlen]=DesStation;
		if(*pPathNum>1 && pPathes[(*pPathNum)-2][minlen]==0)
			pPathes[(*pPathNum)-2][minlen]=DesStation;
	}
}

int SearchMinPathes(unsigned int SrcStation,
                    unsigned int DesStation,
                    unsigned int* pPathNum,
                    unsigned int* pPathLen,
                    unsigned int **ppPathes)
{
    /* 在这里实现功能 */

	if(SrcStation==DesStation)return -1;
	int i,j,newsta,findflag=0;
	int minlen=1,count=0;
	int pathnum=0;
	int sum=0;
	queue<int>qsta;

	for(i=0;i<MAX;i++)
		myfront[i].clear();

	memset(flag,0,sizeof(flag));

	for(i=0;i<station_reach[SrcStation].size();i++)
	{
		myfront[station_reach[SrcStation][i]].push_back(SrcStation);
		if(station_reach[SrcStation][i]==DesStation)
		{
			*pPathNum=1;
			*pPathLen=1;
			*ppPathes=(unsigned int *)malloc(2*sizeof(unsigned int));
			(*ppPathes)[0]=SrcStation;
			(*ppPathes)[1]=DesStation;
			return 0;
		}
		qsta.push(station_reach[SrcStation][i]);
		//count++;
	}
	flag[SrcStation]=1;

	findflag=0;
	while(!qsta.empty() && !findflag)
	{

		minlen++;
		count=qsta.size();
		while(count--){
			newsta=qsta.front();
			flag[newsta]=1;
			for(i=0;i<station_reach[newsta].size();i++)
			{
				if(flag[station_reach[newsta][i]]==0)
					for(j=0;j<myfront[station_reach[newsta][i]].size();j++)
						if(myfront[station_reach[newsta][i]][j]==newsta)break;
				if(j==myfront[station_reach[newsta][i]].size())
					myfront[station_reach[newsta][i]].push_back(newsta);
				if(station_reach[newsta][i]==DesStation)
				{
					findflag=1;
					break;
					/*
					*ppPathes=(unsigned int *)malloc((minlen+1)*sizeof(unsigned int));
					(*ppPathes)[minlen]=DesStation;
					for(j=minlen-1,k=DesStation;j>=0;j--)
						(*ppPathes)[j]=front[(*ppPathes)[j+1]];
					pathnum++;
					*/
				}
				if(flag[station_reach[newsta][i]]==0)qsta.push(station_reach[newsta][i]);
			}
			qsta.pop();
		}
	}

	//if(qsta.empty()) return -1;
/*
	for(i=1;i<12;i++){
		cout<<i<<"站:";
	   for(j=0;j<myfront[i].size();j++)
		   cout<<myfront[i][j]<<" ";
	   cout<<endl;
	   }
	   */
	if(findflag)
	{
		*pPathLen=minlen;
		*pPathNum=0;
		dfs(SrcStation,DesStation,minlen,pPathLen,pPathNum,ppPathes);

	}
	else return -1;
	//cout<<minlen<<" "<<DesStation<<" "<<sum<<endl;
	return 0;
}

/*************************************************************************************************
函数说明:输出从起点站到终点站的最优路线
函数原型:int SearchBestPathes(unsigned int SrcStation,
                               unsigned int DesStation,
                               unsigned int *pPathNum,
                               unsigned int* pPathLen,
                               unsigned int** ppPathes);
输入参数:
         SrcStation 起点站;
         DesStation 终点站;
         Output Param
         pPathNum 最优路线条数;
         pPathLen  最短路线长度;
         ppPathes 存储最短路线的内存地址,内存格式见下图,内存空间在本函数内申请,调用者释放;
返回值 :
         0:成功
         -1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等)
**************************************************************************************************/
int SearchBestPathes(unsigned int SrcStation,
                     unsigned int DesStation,
                     unsigned int *pPathNum,
                     unsigned int* pPathLen,
                     unsigned int** ppPathes)
{
    /* 在这里实现功能 */

    return 0;
}

/*************************************************************************************************
函数说明:清空所有的线路信息
函数原型:void Clear();
输入参数:无
输出参数:无
返回值  :无
**************************************************************************************************/
void Clear()
{

    /* 在这里实现功能 */
//	vector<int>station_reach[MAX];
	for(int i=0;i<MAX;i++)
		station_reach[i].clear();
    return ;

};
int main()
{
	unsigned int Line1[] = {1,2,3,4,5};
	unsigned int Line2[] = {1,10,9,7,6};
	unsigned int Line3[] = {5,7,8};
	unsigned int Line4[] = {11,5};
    int Ret,i;
	unsigned int pPathNum,pPathLen,*ppPathes[70]={NULL};
    AddLine(1,5,&Line1[0]);
	AddLine(2,5,&Line2[0]);
	AddLine(3,3,&Line3[0]);
	AddLine(4,2,&Line4[0]);

    cout<<CalcMinPathLen(1, 11)<<endl;
	SearchMinPathes(1,11,&pPathNum,&pPathLen,ppPathes);
    cout<<pPathLen<<" "<<pPathNum<<endl;
	for(Ret=0;Ret<pPathNum;Ret++)
	{
		for(i=0;i<=pPathLen;i++)
			cout<<ppPathes[Ret][i]<<" ";
		cout<<endl;
	}
	Clear();
	if(SearchMinPathes(1,11,&pPathNum,&pPathLen,ppPathes)==-1)cout<<"NO"<<endl;
	cout<<CalcMinPathLen(1, 11)<<endl;
	return 0;
}
时间: 2024-10-05 00:39:06

华为内部员工测评题——地铁站最佳路线推荐的相关文章

华为内部解读:任正非最厉害的秘密(发钱是艺术,以客户为中心,以奋斗中为本)

大家如果了解华为的人力资源管理体系,它主要是几大模块,一个是绩效管理模块,一个是薪酬管理体系模块,一个是任职资格管理体系模块.这三大模块是人力资源最主要的内容. 2013年12月4—6日,走进华为第四期活动在华为深圳总部举行.在6日上午的培训上,围绕华为的价值观与管理之道,华为前副总裁.曾全程主导华为人力资源管理体系建立的张建国先生与众位岛邻进行了分享. 张建国指出,企业家分三类,第一类是技术型,公司的寿命取决于产品的寿命;第二类是销售型,公司能做多大,取决于老板能掌握多少客户资源;第三类是既不

华三”保卫战”:内部员工详述集体抵制毛渝南的背后隐情

编者按:华三的董事长换任风波已经有愈演愈烈的趋势,对于华三的众多员工来说,换上毛渝南当老总或许是惠普公司又要将华三卖出去的信号,又或许是华三员工持股上市的梦想破灭,但这些我们都是不得而知的,对华三来说这可能真不是一件好事. 前情回顾:近日,有消息称惠普宣布任命中国惠普董事长毛渝南兼任H3C华三董事长一职,原华三董事长Matt Greenly将担任副董事长.这一消息先在华三内部炸开了锅,1月19日华三员工发起了集体抗议活动.据ITValue接到的线索,18日当晚华三地方办公室的员工,特别是销售人员

华为对员工的16条要求

    1.重在参与,敢于向自己挑战 任正非告诫员工,做一件事无论是否成功,你都要找到自己的那份感觉.只要你参与并与之拼搏过,你就是成功了,“胜负无定数,敢搏成七分”.     2.重视向别人学习,取长补短 任正非说,做人要积极吸收别人的优点,对夥伴则应积极指出他的缺点.别人指出你的缺点,批评你的缺点实际上是在帮助你,希望你进步,如果你把这种帮助也放弃了,那就太亏了.     3.要善于归纳总结 任正非与员工座谈时说,现在给你一把丝线,你是不能把鱼给抓住的.你一定要将这把丝线结成网,这种网就有一

[华为机试真题]66.单词搜索

题目 代码 /*--------------------------------------- * 日期:2015-07-06 * 作者:SJF0115 * 题目:WordSearch * 来源:华为机试真题 -----------------------------------------*/ #include <iostream> #include <string> #include <vector> #include <stack> #include

[华为机试真题][2015]65.和尚挑水

题目 某寺庙里7个和尚:轮流挑水,为了和其他任务不能冲突,各人将有空天数列出如下表: 和尚1: 星期二,四; 和尚2: 星期一,六; 和尚3: 星期三,日; 和尚4: 星期五; 和尚5: 星期一,四,六; 和尚6: 星期二,五; 和尚7: 星期三,六,日; 请将所有合理的挑水时间安排表 思路 回朔法求解 回朔法即每进行一步,都试图在当前部分解的基础上扩大该部分解.扩大时,首先检查扩大后是否违反了约束条件,若不违反,则扩大之,然后继续在此基础上按照类似的方法进行,直至成为完整解:若违反,则放弃该步

微软内部员工级别划分

Topic 1: Regarding Level In general, a college grad dev or PM will start at 59. 59 and 60 are level 1 (ie, PM) 61 and 62 are level 2 (ie, PM II) 63 and 64 are Senior (ie, Senior PM) 65 through 67 are Principal 68+ are Partner, Director, GM, etc. Titl

[华为机试真题]70.分苹果

题目 M个相同苹果放到N个相同篮子里有多少种放法,允许有篮子不放. 1<=M<=10,1<=N<=10 例如5个苹果三个篮子,3,1,1 和 1,1,3是同一种放法 输入 7 3 输出 8 思路 设f(m,n) 为m个苹果,n个盘子的放法数目: 当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响.即if(n>m) f(m,n) = f(m,m) 当n<=m:不同的放法可以分成两类: (1)有至少一个盘子空着,即相当于f(m,n) = f(m

[华为机试真题]69.姓名的夫妻相

题目 在中国,形容夫妻恩爱的词汇中,大家用的比较多的就是"夫妻相".所谓"夫妻相",就是两个人看上去比较般配,长相.身材等某些方面有一定的相似度. 本题则另辟蹊径,从人的姓名维度,以字母重复个数来寻找最具"夫妻相"的人. 题目中预先给定一组女士的姓名拼音.输入男士的姓名拼音(拼音中间可以有空格,字母全部小写),依预先给定姓名拼音的先后遍历所有姓名,输出字母重复数最多的女士姓名. 规则1:如果字母重复数最多的女士有多位相同,则以最先匹配的女士做为最

[华为机试真题][2014]63.等式变换

题目 输入一个正整数X,在下面的等式左边的数字之间添加+号或者-号,使得等式成立. 1 2 3 4 5 6 7 8 9 = X 比如: 12-34+5-67+89 = 5 1+23+4-5+6-7-8-9 = 5 请编写程序,统计满足输入整数的所有整数个数. 输入: 正整数,等式右边的数字 输出: 使该等式成立的个数 样例输入:5 样例输出:21 代码 /*--------------------------------------- * 日期:2015-07-06 * 作者:SJF0115 *