题目:
在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;
}