java实现第二届蓝桥杯地铁换乘(C++)

地铁换乘、

为解决交通难题,某城市修建了若干条交错的地铁线路,线路名及其所属站名如stations.txt所示。

线1
苹果园
....
四惠东

线2
西直门
车公庄
....
建国门

线4
....

其中第一行数据为地铁线名,接下来是该线的站名。
当遇到空行时,本线路站名结束。

下一行开始又是一条新线....直到数据结束。


如果多条线拥有同一个站名,表明:这些线间可以在该站换车。

为引导旅客合理利用线路资源,解决交通瓶颈问题,该城市制定了票价策略:

1. 每条线路可以单独购票,票价不等。
2. 允许购买某些两条可换乘的线路的联票。联票价格低于分别购票。

单线票价和联合票价如 price.txt 所示。

线1 180
.....
线13 114
线1,线2 350
线1,线10 390
.....


每行数据表示一种票价
线名与票价间用空格分开。如果是联票,线名间用逗号分开。
联票只能包含两条可换乘的线路。

现在的问题是:根据这些已知的数据,计算从A站到B站最小花费和可行的换乘方案。

比如,对于本题目给出的示例数据

如果用户输入:
五棵松,奥体中心

程序应该输出:
-(线1,线10)-线8 = 565

如果用户输入:
五棵松,霍营

程序应该输出:
-线1-(线4,线13) = 440

可以看出,用户输入的数据是:起始站,终到站,用逗号分开。
程序输出了购票方案,在括号中的表示联票,短横线(-)用来分开乘车次序。
等号后输出的是该方案的花费数值。


请编程解决上述问题。
注意:
1. 我们测试您的程序时,所用数据与题目中的示例数据不同,但格式完全一样。
2. 当多个方案有相同的最小花费,输出任意一个方案即可。


要求考生把所有类写在一个文件中。
调试好后,存入与考生文件夹下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。请不要使用package语句。

Java解法

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class js_04 {
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		String input=null;
		String[] tmp=null;
		while(scanner.hasNextLine()){
			input=scanner.nextLine();
			tmp=input.split(",");
			new js_04(tmp[0],tmp[1]);
		}
	}
	public js_04(String start,String end){
		//解析stations.txt文件,初始化站点信息
		initStations();
		//初始化线路相连信息
		initLines();
		//解析price.txt文件,初始化价格信息
		initPrice();
		input(start,end);
		startProcess();
	}
	//起始站集合
	private List<String> start=new ArrayList<String>();
	//终点站集合
	private List<String> end=new ArrayList<String>();
	//输入起始站和终点站
	public void input(String stationA,String stationB){
		//找到该站属于哪条线
		Iterator<String> it=stationsMap.keySet().iterator();
		String stations=null;
		String line=null;
		while(it.hasNext()){
			line=it.next();
			stations=stationsMap.get(line);
			if(stations.contains(stationA+",")){
				//添加到开始线路集合
				start.add(line);
			}
			if(stations.contains(stationB+",")){
				//添加到结束线路集合
				end.add(line);
			}
		}
	}
	//开始正式处理
	public void startProcess(){
		for(String st:start){
			for(String en:end){
				Line cuStart=lines.get(st);
				cuStart.isUse=true;
				process.add(cuStart);
				nfs(cuStart,lines.get(en));
				process.remove(cuStart);
				cuStart.isUse=false;
			}
		}
		//输入最终结果
		if(minPriceProcess!=null){
			System.out.print(minPriceProcess+" = ");
			System.out.println(minPrice);
		}else{
			System.out.println("不可达");
		}
	}
	//存储遍历过程
	private List<Line> process=new ArrayList<Line>(); 
	public void nfs(Line startLine,Line endLine){
		//结束找到符合要求的路径
		if(startLine.equals(endLine)){
			calPrice();
		}else{
			//遍历所有的可连接节点
			for(Line line:startLi
  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 30
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值