本文主要是介绍河南省第十二届ACM省赛-D地铁1号线,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
看到省赛的原题已经上传至NYOJ了,准备重温一下
某市1号地铁线, 每天6:00 从始发站发出第一趟地铁,以后每隔 m 分钟发出下一趟,直到晚上22:00发出当日最后一趟地铁。
经过运行 X 年的数据分析发现,每趟地铁的车票收入与它的起发时间有一定关联。比如:6:00发出的地铁,由于坐车人数少,一趟下来车票收入为4.50千元;8:00发出的地铁,由于坐车人多,一趟下来车票收入为12.00千元。不同段时间内起发的地铁,车票收入满足不同的线性关系。
输入描述:
第一行: T表示以下有T组测试数据( 1≤ T ≤ 8 )
对每组数据,第1行有两个整数 m n ,接下来有n行,每行两个数据,格式为: hh:mm x 分别表示发车时间和车票收入。其中: 10≤ m ≤ 60 1 ≤ n ≤ 100 0.00 ≤ x ≤ 100000.00
输出描述:
对每组测试数据,输出一个实数,1号地铁线一天的车票总收入。(精确到小数点后2位)
样例输入:
1
60 3
06:00 4.50
08:00 12.00
22:00 12.00
样例输出:
192.75
这题有个挖坑的地方就是6点和12点不一定是发车始终时间,发车始终时间需要从输入数据中获取,分别是最小和最大时间点。
关于收益,如果在输入的时间点上,那么收益就是对应的输入数据。对于不在时间点上的收益,可以采用斜率计算,比如样例中
06:00(4.50)到08:00(12.00)之间存在时间点7:00发车,转换成分钟就是420分发车,位于360与480分钟的区间,收益计算为
4.50+(420-360)*(12.00-4.50)/(480-360),这类似于给定两点求出一次函数,然后计算其中某点的函数值f(x)。
代码如下:
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
void slove(int step,int time){vector<int> vec;//保存时间点map<int,double> mp;//时间点和费用映射关系for(int i=0;i<time;i++){//输入int h,m;double mon;scanf("%d:%d",&h,&m);cin>>mon;vec.push_back(h*60+m);mp[h*60+m]=mon;}sort(vec.begin(),vec.end());//时间点排序double fee=0.0;//总收益int base=0;//时间所在区间标记for(int i=vec[0];i<=vec[time-1];i+=step){if(base<time-1){//标记判断if(i>vec[base+1]){base++;}}if(i==vec[base]){//位于标记头则费用增加fee+=mp[vec[base]];cout<<i<<endl;}else{double a=mp[vec[base+1]]-mp[vec[base]],b=vec[base+1]-vec[base],len=i-vec[base];//斜率算费用fee+=mp[vec[base]]+(a/b)*len;}}printf("%.2f\n",fee);
}
int main()
{int n;cin>>n;while(n--){int step,time;cin>>step>>time;slove(step,time);}return(0);
}
tips:NYOJ这题的样例似乎是传错了,导致这题无法AC(但是算法可以保证是对的,因为比赛现场这题我通过了)
这篇关于河南省第十二届ACM省赛-D地铁1号线的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!