java计算乘地铁费用_蓝桥杯-地铁换乘
为解决交通难题,某城市修建了若干条交错的地铁线路,线路名及其所属站名如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语句。
另外,源程序中只能出现JDK1.5中允许的语法或调用。不能使用1.6或更高版本。
解析:
1.先处理所有的站点,求出所有线路的交叉线路,将线路看成图的一个结点,任何两条线路如果彼此交叉,则这两个线路结点相连。
2.先确定开始站和结束站在哪条线路上,然后将问题转而求从某个结点到另一个结点的路径
3.遍历以上定义的图,可以得出所有符合条件的路径,然后对每一个路径求价钱(因为有联票,所以一条路径可能有多种价钱,如存在这样一条路径:线路1-线路2-线路3-线路4,如果线路2和线路3是可以联票的,则有”线路1-(线路2,线路3)-线路4″的情况出现)
4.每次对符合要求的路径求得对应的价钱,则和最小价钱对比,比其小则保留最少价钱的方案
(备注:这道题实现的时候没有使用分支限界法,效率上打了折扣,如果用分支限界法来遍历线路图,可以提高不少性能)
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 start=new ArrayList();
//终点站集合
private List end=new ArrayList();
//输入起始站和终点站
public void input(String stationA,String stationB){
//找到该站属于哪条线
Iterator 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 process=new ArrayList();
public void nfs(Line startLine,Line endLine){
//结束找到符合要求的路径
if(startLine.equals(endLine)){
calPrice();
}else{
//遍历所有的可连接节点
for(Line line:startLine.connLines){
//已经遍历过则跳过
if(line.isUse)continue;
line.isUse=true;
process.add(line);
nfs(line,endLine);
process.remove(line);
line.isUse=false;
}
}
}
//存储最少价钱
private int minPrice=Integer.MAX_VALUE;
private void calPrice(){
length=process.size();
String calProcss="";//存储过程
cal(0,0,calProcss);
}
private int length;
private String minPriceProcess;
//lineIndex表示当前要处理的路线的下标
public void cal(int lineIndex,int currPrice,String calProcess){
if(lineIndex>=length){
if(currPrice
minPriceProcess=calProcess;
minPrice=currPrice;
}
return;
}
if(lineIndex==length-1){
Line line=process.get(lineIndex);
currPrice+=line.price;
if(currPrice
minPrice=currPrice;
minPriceProcess=calProcess+"-"+line;
}
return;
}else{
Line one=process.get(lineIndex);
Line two=process.get(lineIndex+1);
if(currPrice+one.price>=minPrice)return;
cal(lineIndex+1,currPrice+one.price,calProcess+"-"+one);
int connPrice=isConnection(one,two);
if(connPrice!=-1){//可以相连,则考虑相连的情况
if(currPrice+connPrice>=minPrice)return;
cal(lineIndex+2,currPrice+connPrice,calProcess+"-("+one.name+","+two.name+")");
}
}
}
//判断两条线路是否联票,是则返回联票价钱,否则返回-1
public int isConnection(Line one,Line two){
String key=one.name+","+two.name;
Integer value=connLines.get(key);
if(value==null)return -1;
return value;
}
//用于保存所有的线路信息,key为线路名,value为该线路下的所有站点
private Map stationsMap=new HashMap();
//存储线路的集合,通过路线名获得路线类对象
private Map lines=new HashMap();
public void initStations(){
try {
File file=new File("stations.txt");
BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream(file)));
StringBuilder value=new StringBuilder();
String content=null;
String key=null;
boolean isHead=true;//是否是线路名
while((content=reader.readLine())!=null){
if("".equals(content)){//一条线路读取结束
//将线路存储起来
Line line=new Line();
line.name=key;
lines.put(key, line);
stationsMap.put(key, value.toString());
isHead=true;
value.delete(0, value.length());
}else{
if(isHead){//第一个为线路名
key=content;
isHead=false;
}else{
value.append(content).append(",");
}
}
}
Line line=new Line();
line.name=key;
lines.put(key, line);
stationsMap.put(key, value.toString());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//初始化线路连接情况
public void initLines(){
List list=new ArrayList(stationsMap.keySet());
int length=list.size();
for(int i=0;i
for(int j=i+1;j
//线路名
process(list.get(i),list.get(j));
}
}
}
//处理所有交叉线路
public void process(String l1,String l2){
String line1=stationsMap.get(l1);
String line2=stationsMap.get(l2);
String[] strs=line1.split(",");
for(String str:strs){
if(line2.contains(str+",")){//如果两个路线有共同站点,说明交叉
Line line01=lines.get(l1);
Line line02=lines.get(l2);
line01.connLines.add(line02);
line02.connLines.add(line01);
return;
}
}
}
//联票路线
private Map connLines=new HashMap();
//初始化价钱列表,获得联票信息
public void initPrice(){
try {
File file=new File("price.txt");
BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String content=null;
String[] keyValue=null;
int price=0;
while((content=reader.readLine())!=null){
keyValue=content.split(" ");
price=Integer.valueOf(keyValue[1]);
if(keyValue[0].contains(",")){//联票
connLines.put(keyValue[0], price);
}else{//单条路线
lines.get(keyValue[0]).price=price;
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//自定义线路类
class Line{
//线路名
public String name;
//是否遍历过
public boolean isUse;
//和该路线交叉的路线
List connLines=new ArrayList();
//该路线的价钱
public int price;
@Override
public boolean equals(Object obj) {
return this.name.equals(((Line)obj).name);
}
@Override
public String toString() {
return this.name;
}
}
}
java计算乘地铁费用_蓝桥杯-地铁换乘相关推荐
- Java语言strcmp函数用法_蓝桥杯 算法提高 11-1实现strcmp函数 (JAVA方法)
蓝桥杯 算法提高 11-1实现strcmp函数 (JAVA方法) 首先这不是一个多难的题,但是网上的我没怎么找到有Java的代码,基本全都是c语言的,小编是个小白,如果有不对的地方请联系小编 问题描述 ...
- java. 三个人比赛怎么写_蓝桥杯——分组比赛(2017JavaB组第3题)
分组比赛(17JavaB3) 9名运动员参加比赛,需要分3组进行预赛. 有哪些分组的方案呢? 标记运动员为 A,B,C,... I 下面的程序列出了所有的分组方法: ABC DEF GHI ABC D ...
- java 算法提高 邮票面值设计 蓝桥杯1046
java 算法提高 邮票面值设计 蓝桥杯1046 算法提高 邮票面值设计 思路 代码 算法提高 邮票面值设计 Description 给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤13) ...
- 刷算法题需要的java语法_蓝桥杯java b组需要重点刷什么算法呢?
我觉得这个问题我很适合回答.不过距离我最后一次参赛,已经有了三年,所以回答的内容重点可能有点偏(建议你,可以到网上找找最新的获奖选手赛后总结看看),但是我觉得应该对你有用. 我本科也在湖北,并且参加过 ...
- 2013蓝桥杯java试题_蓝桥杯2013决赛java本科b组试题.doc
蓝桥杯2013决赛java本科b组试题.doc 试题一:公式求值问题描述输入n,m,k,输出下面公式的值.其中C_n^m是组合数,表示在n个人的集合中选出m个人组成一个集合的方案数.组合数的计算公式如 ...
- 蓝桥杯Java历年真题与答案_蓝桥杯大赛java历年真题及答案整理(闭关一个月呕心沥血整理出来的)...
蓝桥杯大赛java历年真题及答案整理(闭关一个月呕心沥血整理出来的) 1蓝桥杯 java 历年真题及答案整理(闭关一个月,呕心沥血整理出来的)1. 算法是这样的,如果给定 N 个不同字符,将这 N 个 ...
- 复数幂用java程序怎么求_蓝桥杯——复数幂 (2018JavaAB组第3题)
18年Java蓝桥杯A组第3题和B组是一样的. 第三题往往比较难. 复数幂 (18JavaAB3) (A.B两卷第三题一样) 设i为虚数单位.对于任意正整数n,(2+3i)^n 的实部和虚部都是整数. ...
- java蓝桥杯加法变乘法_蓝桥杯-加法变乘法-java
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...
- 蓝桥杯研究生c语言试题答案,蓝桥杯试题_蓝桥杯 你有蓝桥杯历年的试题吗最好有参考答案啊 高职高专组C语言的 有的话麻烦你发给我 万分感谢_淘题吧...
❶ 蓝桥杯 你有蓝桥杯历年的试题吗最好有参考答案啊. 高职高专组C语言的 有的话麻烦你发给我 万分感谢 我有真题.但是老师没给答案 ❷ 为什么蓝桥杯试题集评测老是错 楼上的网友说的很简单,实际上因为每 ...
最新文章
- 十五个常用的 Laravel 集合(Collection)
- 调整/home和/root空间容量
- python如何检测和处理异常_Python-20 异常处理 异常检测
- SpringCloud 应用在 Kubernetes 上的最佳实践 — 高可用(熔断)
- VTK:几何对象之ColoredLines
- wpf window 不执行show 就不能load执行_关于机器学习中的Scikit-Learn,你不知道的10个实用功能...
- tree方法php,jsTree详细使用说明
- 钉钉web版防撤回、屏蔽已读
- Chrome Firefox for Linux 直达下载链接
- 第八章--注册码是怎样炼成的
- 程序员常用英语单词1700
- Flash游戏开发中的人物走动实现方法
- 5、Hive数据仓库——Hive分区及动态分区
- 安卓支付宝抢红包脚本软件
- 电子邮箱地址是什么?如何找回电子邮箱的地址呢?
- linux 加速度传感器数据获取,对加速度传感器的数据进行方向和坐标的转换
- 计算机超级账号密码,获取光猫超级用户密码,自己动手分分钟搞定!
- 计算机信息安全技术学习资料汇总
- 无人机——舵机篇(七)
- 高德地图 zoom地图级别无效问题