目录:算法日记
题目描述
奶牛贝茜正在参加冬季哞林匹克运动会的越野滑雪比赛。
她以每秒 米的速度出发。
但是,随着时间的推移,她变得越来越疲倦,她开始放慢脚步。
每次放慢脚步,贝茜的速度都会降低:减速一次后,她以每秒 米的速度移动,减速两次后,则以每秒 米的速度移动,依此类推。
你将被告知何时何地贝茜会减速。
当减速信息格式为:
T 17
意味着,贝茜在某个时间点减速,本例表示比赛开始第 秒贝茜减速。
当减速信息格式为:
D 10
意味着,贝茜在某个地点减速,本例表示在行进 米处减速。
给定 个减速信息,请计算贝茜滑完一千米需要多少秒。
将你的答案四舍五入到最接近的整数( 向上舍入为 )。
输入格式
第一行包含整数 。
接下来 行,每行描述一个减速信息,格式为 T x 或 D x。
无论哪种情况, 都是一个整数,保证所有减速都在贝茜滑完一千米前发生。
可能同时发生多次减速,那么这会使得贝茜的速度一下子变慢很多。
所有减速信息不一定按顺序给出。
输出格式
输出贝茜滑完一千米所需的总时间。
数据范围
输入样例
2
T 30
D 10
输出样例
2970
算法思路
如果仅考虑时间减速或地点减速,把对应序列排个序计算就可以完成。这里比较难处理的是同时存在时间减速和地点减速。单个序列好处理,因此考虑能否把时间序列和地点序列进行合并,并且需要保证排序后的序列无论是从时间还是地点看,仍是升序。
因此,我们设当前所处地点为,当前所处时间为,为了保证与可以比较大小,引入速度。由于题目中速度从开始以(n为减速次数)的方式减小,为了方便处理,我们取为速度的倒数,设a[i]表示时间序列,b[j]表示地点序列,离当前位置最近的点(与表示同一位置,同时更新)先减速,不妨以时间为衡量单位,则:
按上述大小关系进行二路归并。
AC代码
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<int> a, b;
int n;
char op;
int x;
int main() {
cin>>n;
while(n--) {
cin>>op>>x;
if(op == 'T') a.push_back(x);
else b.push_back(x);
}
b.push_back(1000);
sort(a.begin(), a.end());
sort(b.begin(), b.end());
double s = 0;
double t = 0;
double v = 1;
int i = 0;
int j = 0;
while(i < a.size() || j < b.size()) {
if(j == b.size() || i < a.size() && a[i] - t < (b[j] - s) * v) {
s += (a[i] - t) / v;
t = a[i];
i += 1;
v += 1;
} else {
t += (b[j] - s) * v;
s = b[j];
j += 1;
v += 1;
}
}
printf("%.0lf", t);
return 0;
}