[Uva Error Curves]一些二次函数取max的交集还是一个下凸函数。三分即可
#include <bits/stdc++.h> #define maxn 10010 using namespace std; int n, a[maxn], b[maxn], c[maxn]; #define F(i, x) a[i] * x * x + b[i] * x + c[i] inline double cal(double x){ double ret = -1e12; for(int i = 1; i <= n; i ++) ret = max(ret, F(i, x)); return ret; } inline void solve(){ double l = 0, r = 1000; for(int i = 1; i <= 300; i ++){ double len = (r - l) / 3; double m1 = l + len, m2 = r - len; if(cal(m1) < cal(m2))r = m2; else l = m1; } printf("%.4lf\n", cal(l)); } int main(){ int test; scanf("%d", &test); while(test --){ scanf("%d", &n); for(int i = 1; i <= n; i ++) scanf("%d%d%d", &a[i], &b[i], &c[i]); solve(); } return 0; }
[Zoj Light Bulb]列出数学式子,是一个对勾函数(可以直接解),或者三分,注意影子到地上的判断,不过D-x≤H??
#include <bits/stdc++.h> using namespace std; double H, h, D, P, Q; inline double check(double x){ return -x + P / x + Q; } void solve(){ P = D * (h - H), Q = D + H; double l = 1e-9, r = min(H, D); for(int i = 1; i <= 1000; i ++){ double len = (r - l) / 3; double m1 = l + len, m2 = r - len; if(check(m1) > check(m2))r = m2; else l = m1; } printf("%.3lf\n", check(r)); } int main(){ int test; scanf("%d", &test); while(test --){ scanf("%lf%lf%lf", &H, &h, &D); solve(); } return 0; }
[HDU Line belt]三分套三分
#include <bits/stdc++.h> using namespace std; struct Point{ double x, y; inline void read(){scanf("%lf%lf", &x, &y);} }A, B, C, D; #define Sqr(x) (x)*(x) double Len(const Point& a, const Point& b){ return sqrt(Sqr(a.x-b.x) + Sqr(a.y-b.y)); } int P, Q, R; double T(double a, double b){ Point X, Y; X.x = a * (B.x - A.x) + A.x; X.y = a * (B.y - A.y) + A.y; Y.x = b * (C.x - D.x) + D.x; Y.y = b * (C.y - D.y) + D.y; return Len(A, X) / P + Len(D, Y) / Q + Len(X, Y) / R; } double check(double a){ double l = 0, r = 1; while(r - l > 1e-6){ double len = (r - l) / 3.0; double m1 = l + len, m2 = r - len; if(T(a, m1) < T(a, m2))r = m2; else l = m1; }return T(a, r); } int main(){ int test; scanf("%d", &test); while(test --){ A.read(), B.read(), C.read(), D.read(); scanf("%d%d%d", &P, &Q, &R); double l = 0, r = 1; while(r - l > 1e-6){ double len = (r - l) / 3.0; double m1 = l + len, m2 = r - len; if(check(m1) < check(m2))r = m2; else l = m1; } printf("%.2lf\n", check(r)); } return 0; }
时间: 2024-10-02 02:19:40