2 2 0 0 1 0 2 0 -1 0 2 0 0 1 0 2 1 -1 0
Case #1: 1.00 0.00 Case #2: 1.00 1.00
将任意两点的距离公式写出来是一个开口向上的抛物线,然后所有的子函数都是一个开口向上的抛物线,他们取max肯定也是先减后增的,然后
就用三分法逐步逼近最低点就行,100次计算就完全可以满足精度要求了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 300 + 10; int T, N; struct point { int x, y, vx, vy; }p[maxn]; double MAX(double a, double b) { return a > b ? a : b; } double calc(double tm) { double ans = 0; for (int i = 0; i < N - 1; i++) { point a = p[i]; for (int j = i + 1; j < N; j++) { point b = p[j]; double X = (a.x - b.x) + tm * (a.vx - b.vx); double Y = (a.y - b.y) + tm * (a.vy - b.vy); ans = MAX(ans, X * X + Y * Y); } } return ans; } double getTime() { double l = 0.0, r = 1e6, mid, mmid; for (int i = 1; i <= 100; i++) { mid = (l + r) / 2; mmid = (mid + r) / 2; calc(mid) < calc(mmid) ? r = mmid : l = mid; } return mid; } int main() { scanf("%d", &T); for (int t = 1; t <= T; t++) { scanf("%d", &N); for (int i = 0; i < N; i++) { scanf("%d%d%d%d", &p[i].x, &p[i].y, &p[i].vx, &p[i].vy); } double tm = getTime(); printf("Case #%d: %.2f %.2f\n", t, tm, sqrt(calc(tm))); } return 0; }