【程序设计基础与实验】地铁售票查询系统

8-1 地铁售票查询系统 (100 分)

问题描述

杭州地铁(Hangzhou Metro)是浙江省杭州市及杭州都市圈各地区的城市轨道交通,其首条线路杭州地铁1号线于2012年11月24日正式开通,使杭州成为华东地区第四个、浙江省首个开通地铁的城市。

截至2021年9月,杭州地铁运营线路共9条,分别为杭州地铁1号线、杭州地铁2号线、杭州地铁4号线、杭州地铁5号线、杭州地铁6号线(含杭富段)、杭州地铁7号线、杭州地铁8号线、杭州地铁9号线、杭州地铁16号线,共设车站180座(换乘站不重复统计),换乘车站27座。运营里程共计约332千米(不含2条市域线)。杭州都市圈轨道交通线网总里程约400千米。

截至2018年9月,杭州市城市轨道交通线网规划总里程539公里, 其中地铁三期建设规划总里程为387.8公里。2022年杭州亚运会前,杭州将形成“11条轨道线+2条市域线”共计13条线路,总长度达516公里的城市轨道交通骨干网络,实现十城区全覆盖。

本大作业要求设计一个地铁售票查询系统,输入起点站名和终点站名,请输出乘坐地铁线路(如有多条,请显示全部的乘车线路)以及费用(最小费用)。

注:
1、为简化票价计算,设定地铁票价按乘坐站数计算;3站(含)内2元,4-6站(含) 3元,7-11站(含) 4元,12-16站(含)5元; 17站(含)以上部分,每增加1元可乘坐5站;
2、起点站和终点站可能在同一线路上,也可能不在同一线路上(需要换乘,复杂的情况可能需要多次换乘);
3、乘坐地铁可能有多种情况,计算费用可能也会不同,请输出最小费用。例如:从建国北路站到三坝站既可以乘坐5号线,也可以乘坐2号线,由于乘坐站数不一样,产生的费用也不一样,请输出最低费用。
4、本系统只需要考虑杭州地铁的1、2、4、5这四条线路,这四条线路的站点都已经按序列出。
5、地铁线路已有指导的文件给出,系统应该从指定的文件中导出线路和地铁站名。

一波潦草的问题分析

基本思路:首先将问题分类,分别是三种情况:错误输入,不换车和换车。

如果起点终点可以在一条线上实现,则不换车,方向为起点→终点;

如果不能在一条线上完成,又已知四条地铁线两两之间都联通,即最多一次换乘必定可以达到目的,则问题转化为寻找连接两条地铁线的中转站点。这里我们可以先用一个数组保存所有可换乘站点名,然后逐个搜索,接通则输出就可以了(我们是要求输入所有方案的)。

最后,如果方案不止一种,还要输出最小费用。

废话不多说先放代码:
#include<stdio.h>
#include<string.h>
char a[20],b[20],name[20];
int i,j,w,k,t,fi,fj;
int fa[6]={-1,-1,-1,-1,-1,-1},fb[6]={-1,-1,-1,-1,-1,-1};//记录输入站点位置
int line[6]={0},count[5]={0};
static int x[6][38];
char s[6][38][20]={
    {""},
    {
	"湘湖站",
	"滨康路站",
	"西兴站",
	"滨和路站",
	"江陵路站",
	"近江站",
	"婺江路站",
	"城站站",
	"定安路站",
	"龙翔桥站",
	"凤起路站",
	"武林广场站",
	"西湖文化广场站",
	"打铁关站",
	"闸弄口站",
	"火车东站站",
	"彭埠站",
	"七堡站",
	"九和路站",
	"九堡站",
	"客运中心站",
	"下沙西站",
	"金沙湖站",
	"高沙路站",
	"文泽路站",
	"文海南路站",
	"云水站",
	"下沙江滨站",
	"杭州大会展中心站",
	"港城大道站",
	"南阳站",
	"向阳路站",
	"萧山国际机场站"},
	{
	"朝阳站",
	"曹家桥站",
	"潘水站",
	"人民路站",
	"杭发厂站",
	"人民广场站",
	"建设一路站",
	"建设三路站",
	"振宁路站",
	"飞虹路站",
	"盈丰路站",
	"钱江世纪城站", 
	"钱江路站",
	"庆春广场站",
	"庆菱路站",
	"建国北路站",
	"中河北路站",
	"凤起路站",
	"武林门站",
	"沈塘桥站",
	"下宁桥站",
	"学院路站",
	"古翠路站",
	"丰潭路站",
	"文新站",
	"三坝站",
	"虾龙圩站",
	"三墩站",
	"墩祥街站",
	"金家渡站",
	"白洋站",
	"杜甫村站",
	"良渚站"},
	{""},
	{
	"池华街站",
	"金家渡站",
	"好运街站",
	"杭行路站",
	"储运路站",
	"平安桥站",
	"独城生态公园站",
	"吴家角港站",
	"桃源街站",
	"皋亭坝站",
	"新天地街站",
	"华中南路站",
	"笕桥老街站",
	"黎明站",
	"明石路站",
	"彭埠站",
	"火车东站站",
	"新风站",
	"新塘站",
	"景芳站",
	"钱江路站",
	"江锦路站",
	"市民中心站",
	"城星路站",
	"近江站",
	"甬江路站",
	"南星桥站",
	"复兴路站",
	"水澄桥站",
	"联庄站",
	"中医药大学站",
	"杨家墩站",
	"浦沿站"},
	{
	"金星站",
	"绿汀路站",
	"葛巷站",
	"创景路站",
	"良睦路站",
	"杭师大仓前站",
	"永福站",
	"五常站",
	"蒋村站",
	"浙大紫金港站",
	"三坝站",
	"萍水街站",
	"和睦站",
	"大运河站",
	"拱宸桥东站",
	"善贤站",
	"西文街站",
	"香积寺路站",
	"杭氧站",
	"打铁关站",
	"建国北路站",
	"万安桥站",
	"城站站",
	"江城路站",
	"候潮门站",
	"南星桥站",
	"长河站",
	"聚才路站",
	"江晖路站",
	"滨康路站",
	"博奥路站",
	"金鸡路站",
	"人民广场站",
	"育才北路站",
	"通惠中路站",
	"火车南站站",
	"双桥站",
	"姑娘桥站"}
	};

void begin(){
	x[1][1]=1;x[5][29]=1;
	x[1][5]=2;x[4][24]=2;
	x[1][7]=3;x[5][22]=3;
	x[1][10]=4;x[2][17]=4;
	x[1][13]=5;x[5][19]=5;
	x[1][15]=6;x[4][16]=6;
	x[1][16]=7;x[4][15]=7;
	x[2][5]=8;x[5][32]=8;
	x[2][12]=9;x[4][20]=9;
	x[2][15]=10;x[5][20]=10;
	x[2][25]=11;x[5][10]=11;
	x[2][29]=12;x[4][1]=12;
	x[4][26]=13;x[5][25]=13;
}//标出所有可换乘站点

void direction(int x,int y){
	if(!x)
	switch(y){
		case 1:strcpy(name,"萧山国际机场方向");break;
		case 2:strcpy(name,"良渚方向");break;
		case 4:strcpy(name,"浦沿方向");break;
		case 5:strcpy(name,"姑娘桥方向");break;
	}
	else switch(y){
		case 1:strcpy(name,"湘湖方向");break;
		case 2:strcpy(name,"朝阳方向");break;
		case 4:strcpy(name,"池华街方向");break;
		case 5:strcpy(name,"金星方向");break;
	}
}//确定地铁乘坐方向
 
int max(int x,int y){
	return (x>y)?1:0;
} 

int money(int n){
	if(n<=3)return 2;
	else if(n<=6)return 3;
	else if(n<=11)return 4;
	else if(n<=16)return 5;
	else return 5+(n-16)/5+1;
}//输入站数,输出费用

int check(char a[],char b[]){
	int k1=0,k2=0;
	for(i=0;i<6;i++){
		for(j=0;j<38;j++)
		{
			if(strcmp(a,s[i][j])==0)
			{
				if(k1!=2)k1=1;
				fa[i]=j;
				
				for(w=0;w<38;w++){
					
					if(strcmp(b,s[i][w])==0){
						if(w==j){//若输入两个站点相同也默认为输入了错误的站点名
							k1=0;
							break;
						}
						else
						{
							k1=2;
				    	    fb[i]=w;
						    line[i]=1;
						    break;
						}
				    	
					}
					
				}
				    
			}
			if(strcmp(b,s[i][j])==0){
				k2=1;
			    fb[i]=j;
			}

		}//记录两个站点的位置用于后续搜索。

}//判断输入的两个站点是否需要换乘,需要则返回1,不需要则返回2,查无此站点返回0
	if(k1==2) return 2;
	 else if(k1==1&&k2==1) return 1;
	  else return 0;
}

int find(int fi,int fj){
	t=0;
	for(i=0;i<38;i++){
		for(j=0;j<38;j++){
			if(x[fi][i]==x[fj][j]&&x[fi][i]!=0&&x[fj][j]!=0){
				direction(max(fa[fi],i),fi);
				printf("乘坐%d号线 (%s),\n",fi,name);
				if(i>fa[fi]){
					for(w=fa[fi];w<=i;w++){
						if(w==fa[fi])printf("上车 :%s ,途经 :",s[fi][w]);
						else if(w==i)printf(" 下车 :%s。",s[fi][w]);
						else printf(" %s,",s[fi][w]);
						count[t]++;
					}
				}//往后坐
				else {
					for(w=fa[fi];w>=i;w--){
						if(w==fa[fi])printf("上车 :%s ,途经 :",s[fi][w]);
						else if(w==i)printf(" 下车 :%s。",s[fi][w]);
						else printf(" %s,",s[fi][w]);
						count[t]++;
					}
				} //往前坐
				direction(max(j,fb[fj]),fj);
				printf("\n乘坐%d号线 (%s),\n",fj,name);//之后换乘下一条线
				if(j<fb[fj]){
					for(w=j;w<=fb[fj];w++){
						if(w==j)printf("上车 :%s ,途经 :",s[fj][w]);
						else if(w==fb[fj])printf(" 下车 :%s。",s[fj][w]);
						else printf(" %s,",s[fj][w]);
						count[t]++;
					}
				}//往后坐
				else {
					for(w=j;w>=fb[fj];w--){
						if(w==j)printf("上车 :%s ,途经 :",s[fj][w]);
						else if(w==fb[fj])printf(" 下车 :%s。",s[fj][w]);
						else printf(" %s,",s[fj][w]);
						count[t]++;
					}
				} //往前坐
				printf("费用 :%d元\n",money(count[t]));
				t++;
			}
		}
	}
	
}//主要是换乘的情况

int mincount(){
int m=count[0];
	for(i=0;i<t;i++)
		if(m>count[i])
			m=count[i];
	return m;
}//最短路线

int main(){
	begin();
    gets(a);
    gets(b);
    if(check(a,b)==0)printf("错误的站点名\n");
    else if(check(a,b)==1) {
    	//printf("换车\n");
    	for(i=0;i<6;i++){
	       if(fa[i]!=-1){
	    	 fi=i;
	    	 for(j=0;j<6;j++)if(fb[j]!=-1)fj=j;
	    	 
			 	find(fi,fj);
			}
		}
		printf("最低费用 :%d元",money(mincount())); 
	}
	else {
		//printf("不换车\n");
		 t=0;
		for(i=0;i<6;i++){
			if(line[i]==1){
				direction(max(fa[i],fb[i]),i);
				printf("乘坐%d号线 (%s),\n",i,name);
				if(fa[i]<=fb[i])
					for(j=fa[i];j<=fb[i];j++)
					{
						if(j==fa[i])printf("上车 :%s ,途经 :",s[i][j]);
						else if(j==fb[i])printf(" 下车 :%s",s[i][j]);
						else printf(" %s,",s[i][j]);
						count[t]++;
					}	
				else 
				    for(j=fa[i];j>=fb[i];j--){
				    	if(j==fa[i])printf("上车 :%s ,途经 :",s[i][j]);
						else if(j==fb[i])printf(" 下车 :%s",s[i][j]);
						else printf(" %s,",s[i][j]);
						count[t]++;
				    }
			    printf("。费用 :%d元\n",money(count[t]));
				t++;
			}	
		} 
		if(t>1)printf("最低费用 :%d元",money(mincount())); 
	}	
    
}
测试用例
(1) 错误的站点名

1.错误输入:比如不存在的站名,或者不写“站”

文新站
丰潭路

在这里插入图片描述

2.起点终点相同输入

沈塘桥站
沈塘桥站

在这里插入图片描述

(2)不换车

1.只有一种坐法

三坝站
金家渡站

在这里插入图片描述

2.多种坐法

建国北路站
三坝站

在这里插入图片描述

(3)换车

1.起点终点都不在换乘点

丰潭路站
市民中心站

在这里插入图片描述
2.起点终点有一个在换车点

凤起路站
姑娘桥站

在这里插入图片描述

3.起点终点都在换车点

凤起路站
南星桥站

在这里插入图片描述

好了,本文到这里就结束了。
( ps:作者是个刚学了一学期c语言的计算机专业的小白,这是我的第一篇文章,写的不好大家多多担待,也欢迎各位路过的大佬批评指正)

  • 8
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值