POJ 4113:北京地铁票价-BeiJing Subway

9 篇文章 0 订阅
做一道水题欢乐一下。


总时间限制:

1000ms
内存限制:
65536kB
描述

从2014年12月28日起,北京市公交地铁将执行新的票价方案。其中地铁的票价方案改为:6公里(含)内3元;6公里至12公里(含)4元;12公里至22公里(含)5元;22公里至32公里(含)6元;32公里以上部分,每增加1元可乘坐20公里。

地铁交通网络有许多线路组成,每条线路又由多个地铁站连接而成(为简化问题,部分线路和部分地铁站被从地图上略去)。比如地铁4号线和1号线的部分地铁站名称和相邻站之间的距离如下表:

4号线 起始/终到车站

区间距离(米)

圆明园——北京大学东门

1295

北京大学东门——中关村

887

中关村——海淀黄庄

900

海淀黄庄——人民大学

1063

人民大学——国家图书馆

2709

国家图书馆——西直门

1958

西直门——西四

3225

西四——西单

1880

西单——宣武门

815

……

1号线 起始/终到车站

区间距离(米)

军事博物馆——木樨地

1166

木樨地——复兴门

1715

复兴门——西单

1590

西单——天安门西

1217

天安门西——天安门东

925

天安门东——王府井

852

……


    如果我们从北京大学东门出发,前往天安门东,需要先乘坐地铁4号线到达西单站,然后在西单换乘地铁1号线,最后到达天安门东。整个行程的路程为:

(887+900+1063+2709+1958+3225+1880)+ (1217+925) = 14764(米)

因此,按照新的票价方案,乘坐地铁从北京大学东门到达天安门东需要花费5元。

    

    现在我们化简地铁网络,假设网络中至多只有2条线路,并且网络要么是“一”字形,要么是“十”字形,不存在环路(从一个站出发经过若干不同的站后又回到出发站)。

现在任意给出两个地铁站,从其中一个出发到达另外一个地铁站的票价是多少?


输入
第一行是一个整数cases(1<=cases<=10),表示测试数据的个数。下面是cases组测试数据。

对于每组测试数据,第一行是两个整数L(1<=L<=2)和D(1<=D<=10),分别表示地铁线路的个数和问题的个数。

然后是L行,每行表示一个地铁线路。每行首先是一个数字M(2<=M<=20),表示这条线路上地铁站的个数。然后是用空格隔开的M个字符串和(M-1)个整数,字符串是M个地铁站的拼音,它们按线路上的顺序依次排列;数字位于两个字符串之间,表示这两个相邻地铁站之间的距离。

然后是D行,每行两个字符串,分别为起点和终点地铁站,要求输出它们之间的票价。输入数据保证线路中存在起点和终点,并且有唯一的路线可达。
输出
对于每组测试数据,首先输出一行”Casei:”,然后是D行,每行代表从起点到达终点地铁站的票价。

注意,不同组测试数据之间的地铁线路不能互用,例如,你不能用第1组测试数据的地铁线路去求解第2组测试数据中的票价。
样例输入
21 25 YuanMingYuan 1295 BeiJingDaXueDongMen 887 ZhongGuanCun 900 HaiDianHuangZhuang 1063 RenMinDaXueBeiJingDaXueDongMen ZhongGuanCunBeiJingDaXueDongMen RenMinDaXue2 110 YuanMingYuan 1295 BeiJingDaXueDongMen 887 ZhongGuanCun 900 HaiDianHuangZhuang 1063 RenMinDaXue 2709 GuaJiaTuShuGuan 1958 XiZhiMen 3225 XiSi 1880 XiDan 815 XuanWuMen7 JunShiBoWuGuan 1166 MuXiDi 1715 FuXingMen 1590 XiDan 1217 TianAnMenXi 925 TianAnMenDong 852 WangFuJingBeiJingDaXueDongMen TianAnMenDong
样例输出
Case 1:33Case 2:5

这题比较简单,就没有使用图的算法,直接在两条线路上进行查找。

这里使用vector容器来存储地铁站的信息,每个vector的元素是一个pair容器,存放站名和该站到下一站的距离。

用map存储每个站的站名信息,这样便于查找每个站点在哪条线路上。

count_price:根据距离来计算票价,这里只要注意一下double到int转换就可以了。

count_distance:根据地铁线路的vector,和两个地铁站的名称来计算两个地铁站之间的距离。

#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;

int count_price(int distance){  // 计算价格
	double km = distance / 1000;
	int price = 0;
	if (km <= 6)
		return 3;
	else if (km > 6 && km <= 12)
		return 4;
	else if (km > 12 && km <= 22)
		return 5;
	else if (km >22 && km <= 32)
		return 6;
	else {
		price = ((km - 32) / 20 + 6 + 1);
		return price;
	}
}

int count_distance(vector<pair<string,int> > lines_info, string station_a, string station_b){
	bool flag = false;
	int total_distance = 0;
	for (vector<pair<string, int> >::iterator it = lines_info.begin(); it != lines_info.end(); ++it){
		if (!flag && ((*it).first == station_a || (*it).first == station_b )){
			flag = true;
			total_distance += (*it).second;
			continue;
		}
		if (flag) {
			total_distance += (*it).second;
		}
		if (flag && ((*it).first == station_a || (*it).first == station_b)){
			total_distance -= (*it).second;
			break;
		}
	}
	return total_distance;
}

int main(){
	int cases, L, D, stations_count;
	string name, station_a, station_b, common_station;
	int distance, total_distance;
	bool flag = false;
	char buffer[50];
	cin >> cases;
	for (int m = 0; m < cases; ++m){
		cout << "Case " << m + 1 << ":" <<endl;
		cin >> L >> D;
		vector<pair<string, int> >* lines_info = new vector<pair<string, int> >[L];  // L是地铁的线路
		map<string, int>* station_names = new map<string, int>[L];  // 用于判断

		// 读入地铁线路的信息
		bool isFind = false;
		for (int i = 0; i < L; ++i){
			cin >> stations_count;
			while (stations_count --){  // 读入地铁站和地铁站到下一站的长度
				if (stations_count != 0)
					cin >> name >> distance;
				else{
					cin >> name;
					distance = 0;
				}
				lines_info[i].push_back(pair<string, int>(name, distance));
				station_names[i].insert(pair<string, int>(name, distance));
				if (i == 1){  // 查找共同站点
					if ( !isFind && station_names[0].find(name) != station_names[0].end()){
						common_station = name;
						isFind = true;
					}
				}
			}
		}

		// 计算路程
		while (D--){
			cin >> station_a >> station_b;
			total_distance = 0;
			if (L == 1)
				cout << count_price(count_distance(lines_info[0], station_a, station_b)) << endl;
			else if (L == 2){
				// 计算的两个站点都位于第一条线路
				if ((station_names[0].find(station_a) != station_names[0].end())
					&& (station_names[0].find(station_b) != station_names[0].end())){
					cout << count_price(count_distance(lines_info[0], station_a, station_b)) << endl;
				}
				// 计算的两个站点都位于第二条线路
				else if ((station_names[1].find(station_a) != station_names[1].end())
					&& (station_names[1].find(station_b) != station_names[1].end())){
					cout << count_price(count_distance(lines_info[1], station_a, station_b)) << endl;
				}
				// 两个站点位于不同的线路
				else{
					if (station_names[0].find(station_a) != station_names[0].end())
						cout << count_price(count_distance(lines_info[0], common_station, station_a)
							+ count_distance(lines_info[1], common_station, station_b)) << endl;
					else
						cout << count_price(count_distance(lines_info[1], common_station, station_a)
							+ count_distance(lines_info[0], common_station, station_b)) << endl;
				}
			}
		}
		delete [] lines_info;
	}
	return 0;
}





  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值