题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3763
AC代码(C++):
#include <iostream> #include <queue> #include <string> #include <algorithm> #define INF 0x3f3f3f3f #define eps 1e-8 using namespace std; double X0, Y0, c, T; double A, B, C; double f(double x) { return A*x*x + B*x + C; } int main() { while (cin >> X0 >> Y0 >> c >> T) { int n; int ans = 0; double x, y, vx, vy; cin >> n; for (int i = 0; i < n; i++) { bool flag = false; cin >> x >> y >> vx >> vy; A = vx*vx + vy*vy - c*c; B = 2 * ((x - X0)*vx + (y - Y0)*vy); C = (x - X0)*(x - X0) + (y - Y0)*(y - Y0); double mid = -(B / (2 * A)); if (mid > eps && mid - T < -eps) { double f0, f1, f2; f0 = f(0); f1 = f(mid); f2 = f(T); if (f0*f1 < eps || f1*f2 < eps || f0*f2 < eps)flag = true; } else { double f0, f1; f0 = f(0); f1 = f(T); if (f0*f1 < eps)flag = true; } B += 4 * T*c*c; C -= 4 * T*T*c*c; mid = (B / (2 * A)); if (mid - T > eps && mid - 2*T < -eps) { double f0, f1, f2; f0 = f(T); f1 = f(mid); f2 = f(2*T); if (f0*f1 < eps || f1*f2 < eps || f0*f2 < eps)flag = true; } else { double f0, f1; f0 = f(T); f1 = f(2*T); if (f0*f1 < eps)flag = true; } if (flag)ans++; } cout << ans << endl; } //system("pause"); }总结: 对精度要求很高的一道题. 道理我都懂, 但就因为精度问题WA了无数次...
算enemy与圆的距离, 发现是个关于t的二次函数, 于是问题就成了二次函数在区间[0,T]和[T,2T]与x轴有无交点. 读过高中的都会吧, 问题是精度, 以前一直认为大于0就写>eps小于0就写<-eps, 但是这题里面判断异号时候却要反过来, 不反过来就会WA!