基础算法:

  1. 枚举
  2. 模拟,高精度
  3. 贪心
  4. 前缀和与差分
  5. 双指针
  6. 二分查找和二分答案
  7. 离散化和区间合并

P0204 小田滑雪

solutionsolution

先分别对时间和距离的两个失误记录进行排序,再用两个双指针 ii , jj 指向时间和距离的数组头,用 disdis 记录当前距离,ansans 记录当前时间,resres 当前失误次数

如果时间记录先,dis+=t[j]ansres{dis += \frac{t[j] - ans}{res}}ans=t[j]ans = t[j]

否者 ans+=(d[i]dist)resans += (d[i] - dist) * resdist=d[i]dist = d[i]

最后再计算一次 ansans

codecode

#include<bits/stdc++.h>
using namespace std;

const int N = 1e4 + 5;

int n , p;
vector<double> d , t;
char op;

signed main(){
	freopen("snow.in" , "r" , stdin);
	freopen("snow.out" , "w" , stdout);
	
	cin >> n;
	for(int i = 1 ; i <= n ; i ++){
		cin >> op >> p;
		if(op == 'T') t.push_back(p);
		else d.push_back(p);
	}
	sort(d.begin() , d.end());
	sort(t.begin() , t.end());
	d.push_back(1e9) , t.push_back(1e9);
	
	int i = 0 , j = 0;
	double dist = 0 , ans = 0 , res = 0;
	
	while(i < d.size() - 1 || j < t.size() - 1){
		res ++;
		if(dist + (t[j] - ans) / res < d[i]){
			dist += (t[j] - ans) / res;
			ans = t[j];
			j ++;
		}else{
			ans += (d[i] - dist) * res;
			dist = d[i];
			i ++;
		}
	}
	ans += (1000 - dist) * (res + 1);
	cout << (long long)(ans + 0.5);
	return 0;
}