The Moving Points
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1754 Accepted Submission(s): 696
For each test case, first line has a single number N (N <= 300), which is the number of points.
For next N lines, each come with four integers Xi, Yi, VXi and VYi (-106 <= Xi, Yi <= 106, -102 <= VXi , VYi <= 102), (Xi, Yi) is the position of the ith point, and (VXi , VYi) is its speed with direction. That is to say, after 1 second, this point will move to (Xi + VXi , Yi + VYi).
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;
}
248



被折叠的 条评论
为什么被折叠?



