华为机试--地铁换乘问题

问题描述:

描述:已知2条地铁线路,其中A为环线,B为东西向线路,线路都是双向的。经过的站点名分别如下,两条线交叉的换乘点用T1、T2表示。编写程序,任意输入两个站点名称,输出乘坐地铁最少需要经过的车站数量(含输入的起点和终点,换乘站点只计算一次)。

地铁线A(环线)经过车站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18

地铁线B(直线)经过车站:B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B1!0 T2 B11 B12 B13 B14 B15

输入:输入两个不同的站名

输出:所经过的站数及站的名称

其实分析问题就会发现,这是一个求最短路径的问题,是图算法的里面比较基础的。常见的求路径的有A星,Dijkstra算法,floyd算法等,由于研究的不深入,就不细谈了。floyd算法可参考http://www.cnblogs.com/twjcnblog/archive/2011/09/07/2170306.html。

#include <iostream>
#include <string>
#include <stack>
using namespace std;
#define  inf 1000   //定义无穷远距离
#define  stationNum 35  //总的站台个数
string station[stationNum]={"A1","A2","A3","A4","A5","A6","A7","A8","A9","A10",
"A11","A12","A13","A14","A15","A16","A17","A18",
"B1","B2","B3","B4","B5","B6","B7","B8","B9","B10",
"B11","B12","B13","B14","B15","T1","T2"} ;
int string_To_int(string st);
 void Ford(int distance[][stationNum],int path[][stationNum]);
  int staNUm(int dis[][stationNum],int path[][stationNum],string start,string destination);

void main()
{
	int path[stationNum][stationNum];
	int distance[stationNum][stationNum];
	Ford(distance,path);
	string start,des;
	cin>>start>>des;
	cout<<staNUm(distance,path,start,des);
}
int string_To_int(string st)
{
	for (int i=0;i<stationNum;i++)
	{
		if (station[i]==st)
		{
			return i;
		}
	}

}
 void Ford(int distance[][stationNum],int path[][stationNum])
 {
	 //距离矩阵初始化其中相邻两项边是联通的,其他边之间都是不通的
	 for (int i=0;i<stationNum;i++)
	 {
		 for (int j=0;j<stationNum;j++)
		 {
			 if (i==j) distance[i][j]=0;
			 else distance[i][j]=inf;
		 }
	 }
	 int lineA[20]={0,1,2,3,4,5,6,7,8,33,9,10,11,12,34,13,14,15,16,17};
	 int lineB[17]={18,19,20,21,22,33,23,24,25,26,27,34,28,29,30,31,32};
	 for (int i=0;i<19;i++)
	 {
		 distance[lineA[i]][lineA[i+1]]=1;
		 distance[lineA[i+1]][lineA[i]]=1;
	 }
	 for (int i=0;i<16;i++)
	 {
		 distance[lineB[i]][lineB[i+1]]=1;
		 distance[lineB[i+1]][lineB[i]]=1;
	 }
	 //初始化path
	 for (int i=0;i<stationNum;i++)
	 {
		 for (int j=0;j<stationNum;j++)
		 {
			 path[i][j]=i;
		 }
	 }

	  for (int k=0;k<stationNum;k++)//注意K的位置!!!!
	 {
		 for (int j=0;j<stationNum;j++)
		 {
			 for (int i=0;i<stationNum;i++)
			 {
				 if (distance[i][j]>distance[i][k]+distance[k][j])
				 {
					 distance[i][j]=distance[i][k]+distance[k][j];
					 path[i][j]=path[k][j];
				 }
			 }
		 }
	 }
 }

 int staNUm(int dis[][stationNum],int path[][stationNum],string start,string destination)
 {
	 int s=string_To_int(start);
	 int d=string_To_int(destination);
	 //因为path[i][j]存的是最后到达j的前一个站点,所以我们要输出路径,就要从后往前遍历path。存放在stack中,最后依次输出即可
	 stack<int> s_stack;
	 for (int i=0;i<stationNum;i++)
	 {
		 for (int j=0;j<stationNum;j++)
		 {
			 if (i==s&&j==d)
			 {
				 int k=j;
				 do
				 {
					 k=path[i][k];
					 s_stack.push(k);
				 } while (k!=i);
				 cout<<station[s_stack.top()];
				 s_stack.pop();
				 while (!s_stack.empty())
				 {
					 cout<<"->"<<station[s_stack.top()];
					 s_stack.pop();
				 }
				  cout<<"->"<<station[j];
				 cout<<endl;
				 return dis[i][j]+1;
			 }
		 }
	 }
 }

代码运行结果如下;

本文参考http://blog.csdn.net/qinhl060343/article/details/37819345

时间: 2024-10-14 20:14:03

华为机试--地铁换乘问题的相关文章

华为机试—地铁换乘(图文吐血整理)

题目:地铁换乘 描述:已知2条地铁线路,其中A为环线,B为东西向线路,线路都是双向的.经过的站点名分别如下,两条线交叉的换乘点用T1.T2表示.编写程序,任意输入两个站点名称,输出乘坐地铁最少需要经过的车站数量(含输入的起点和终点,换乘站点只计算一次). 地铁线A(环线)经过车站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18 地铁线B(直线)经过车站:B1 B2 B3 B4 B5 T1 B6 B7 B8 

华为机试--地铁换乘

[问题] 描述:已知2条地铁线路,其中A为环线,B为东西向线路,线路都是双向的.经过的站点名分别如下,两条线交叉的换乘点用T1.T2表示.编写程序,任意输入两个站点名称,输出乘坐地铁最少需要经过的车站数量(含输入的起点和终点,换乘站点只计算一次). 地铁线A(环线)经过车站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18 地铁线B(直线)经过车站:B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 

华为机试(8)

高级题样题:地铁换乘  描述:已知2条地铁线路,其中A为环线,B为东西向线路,线路都是双向的.经过的站点名分别如下,两条线交叉的换乘点用T1.T2表示.编写程序,任意输入两个站点名称,输出乘坐地铁最少需要经过的车站数量(含输入的起点和终点,换乘站点只计算一次). 地铁线A(环线)经过车站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18 地铁线B(直线)经过车站:B1 B2 B3 B4 B5 T1 B6 B7

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

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

华为机试正式版(西安c/c++/java),今天下午去机试的题目,新鲜出炉了!

以下题目都是回忆的,题目都很简单, 大家有些基础就可以参加!(语言可以是c/c++,也可以是java的) 题目一(60分): 字符串操作, 将小写转换成大写, 将大写转化为小写, 数字的不做转换 例如, 输入:aBcD12 输出:AbCd12 题目二(100分): 将输入的字符串按照规定重新排序,如果字符串长度为奇数, 则中间的字符保持不变, 中间字符左侧降序排列, 右侧字符按照升序排列, 如果字符串长度为偶数,则左半侧字符降序排列,右半侧字符则按照升序排列 例如, 输入:ab5de 输出:ba

华为机试 --- 求最大三位数

题目:输入10位0-9数字,取其中三位不同数字组合,求组合出来的最大三位数. 如输入 1 2 3 4 5 6 7 8 9 0,组合出来987最大. 测试代码如下: #include <stdio.h> #include <stdlib.h> int IsSame(int *a, int num); int main() { int i=0; int j=0; int a[10]={0}; int input =0; int length =0; int temp=0; for (i

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

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

2014华为机试西安地区B组试题

2014华为机试西安地区B组试题 题目一.亮着点灯的盏数 一条长廊里依次装有n(1≤n≤65535)盏电灯,从头到尾编号1.2.3.-n-1.n.每盏电灯由一个拉线开关控制.开始,电灯全部关着. 有n个学生从长廊穿过.第一个学生把号码凡是1的倍数的电灯的开关拉一下:接着第二个学生把号码凡是2的倍数的电灯的开关拉一下:接着第三个学生把号码凡是3的倍数的电灯的开关拉一下:如此继续下去,最后第n个学生把号码凡是n的倍数的电灯的开关拉一下.n个学生按此规定走完后,长廊里电灯有几盏亮着. 注:电灯数和学生

[华为机试]输入数字的汉语拼音,每个拼音的首字母大写。输出该数字的阿拉伯数字。

//输入数字的汉语拼音,每个拼音的首字母大写.输出该数字的阿拉伯数字. //JiuBaiJiuShiJiu -> 999 #include<stdio.h> #include<string.h> int result = 0; void add(int n,char wei[]) { if(strcmp(wei,"Wan") == 0) result = result + n * 10000; else if(strcmp(wei,"Qian&q