当前位置: 代码迷 >> 综合 >> CF24E Berland collider
  详细解决方案

CF24E Berland collider

热度:42   发布时间:2023-12-02 14:33:56.0

题目:

在x轴上有子弹,有的往左发射,有的往有发射,并且每个子弹都有运行速度。
以向右为正方向。
对于输入,按照坐标递增的顺序输入。
1<=n<=5*10^5 vi,xi的绝对值不超过10^9 vi!=0
对于输出,输出第一次子弹相撞的时间,如果不相撞,输出-1

解决:

二分相撞的时间
然后枚举子弹运行后的位置,如果两个子弹运行方向为相向,且本来右边的子弹到了左边子弹的左边,说明相遇了

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
int n;
double x[N], v[N];
bool check(double mid)
{
    // printf("mid = %lf\n", mid);double rr = -1e30;for (int i = 1; i <= n; i ++ ){
    if (v[i] > 0) rr = max(rr, x[i] + v[i] * mid);else{
    double ll = x[i] + v[i] * mid;// if (ll <= rr) return true;if (ll < rr) return true;}}// cout << "-----" << endl;return false;
}
int main()
{
    cin >> n;for (int i = 1; i <= n; i ++ ) scanf("%lf%lf", &x[i], &v[i]);int f = 0;for (int i = 1; i <= n; i ++ )if (v[i] < 0 && v[i + 1] > 0) f ++;else if (v[i] > 0 && v[i + 1] < 0) f += 2;if (f <= 1){
    puts("-1");return 0;}double l = 0, r = 1e9;double last = -1e9;while (fabs(r - l) > 1e-9){
    double mid = (l + r) / 2;// printf("l = %.12lf, r = %.12lf, val = %.12lf\n", l, r, fabs(r - l));// l为1000000000.00000,r也为1000000000.00000结果r-l却是一个小数// 但是当我写.12lf的时候却l又变成了999999999.99999999660000// 运算过程中出现了精度问题if (check(mid)) r = mid;else l = mid;if (last == mid) break;last = mid;}// if (check(r))printf("%.10lf\n", r);// else printf("-1\n");return 0;
}